.\" $OpenBSD: dt.4,v 1.9 2025/10/11 00:54:55 jsg Exp $ .\" .\" Copyright (c) 2019 Martin Pieuchot .\" .\" Permission to use, copy, modify, and distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above .\" copyright notice and this permission notice appear in all copies. .\" .\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" .Dd $Mdocdate: October 11 2025 $ .Dt DT 4 .Os .Sh NAME .Nm dt .Nd dynamic tracer .Sh SYNOPSIS .Cd "pseudo-device dt" .Sh DESCRIPTION System and application tracing can happen in the kernel. It has to be configured and enabled through the .Xr ioctl 2 interface exposed by the pseudo-device .Pa /dev/dt . .Pp This device can only be opened when the .Va kern.allowdt .Xr sysctl 2 variable is set. .Sh IOCTL INTERFACE The .Xr ioctl 2 command codes below are defined in .In dev/dt/dtvar.h . .Bl -tag -width xxxxxx .It Dv DTIOCGPLIST Fa "struct dtioc_probe *dtpr" Get available probe entries. .Bd -literal struct dtioc_probe { size_t dtpr_size; struct dtioc_probe_info *dtpr_probes; }; .Ed .Pp If .Va dtpr_size is non-zero, as many probes as possible that can fit into this size will be copied into the supplied buffer. On exit, .Va dtpr_size is always set to the total size required to hold all probe entries (i.e., it is set to .Li sizeof(struct dtioc_probe_info) * dt_nprobes ) . .It Dv DTIOCGSTATS Fa "struct dtioc_stat *dtst" Get statistics for current recording. .Bd -literal struct dtioc_stat { uint64_t dtst_readevt; uint64_t dtst_dropevt; }; .Ed .It Dv DTIOCRECORD Fa "int on" Start or stop recording. .It Dv DTIOCPRBENABLE Fa "struct dtioc_req *dtrq" Enable the given probe for recording. .Bd -literal struct dtioc_req { uint32_t dtrq_pbn; struct dt_filter dtrq_filter; uint32_t dtrq_rate; uint64_t dtrq_evtflags; }; .Ed .It Dv DTIOCRDVNODE Fa "struct *dtioc_rdvn" Resolve the instruction pointer from the traced process to the ELF object. .Bd -literal struct dtioc_rdvn { pid_t dtrv_pid; int dtrv_fd; caddr_t dtrv_va; caddr_t dtrv_offset; caddr_t dtrv_start; size_t dtrv_len; }; .Ed .Pp The caller populates .Fa dtrv_pid with the process ID of the traced process and .Fa dtrv_va with the program counter address to look up. .Pp On success, the remaining members are populated. .Fa dtrv_fd is the file descriptor to the DSO file that .Fa dtrv_va belongs to. .Fa dtrv_len is the length of the DSO file. .Fa dtrv_offset and .Fa dtrv_start are the relative offset of .Fa dtrv_va to the start of the text segment and the base address of that segment respectively. .Pp To calculate the relative offset of .Fa dtrv_va in the DSO the following calculation can be used: .Pp .Dl iOffset = dtrv_va - dtrv_start + dtrv_offset .Pp The segment can be found by walking the ELF program headers and looking for the mapping where iOffset is included in the range [GElf_Phdr.p_offset, GElf_Phdr.p_offset + GElf_Phdr.p_filesz) .Pp Using the .Vt GElf_Phdr.p_vaddr the base address of the segment can be calculated by .Dl lbase = dtrv_start - GElf_Phdr.p_vaddr .Pp For symbol lookups the offset can now be calculated as .Dl symOffset = dtrv_va - lbase .El .Sh FILES .Bl -tag -width /dev/dt -compact .It Pa /dev/dt dynamic tracing device. .El .Sh ERRORS An open of .Pa /dev/dt will fail if: .Bl -tag -width Er .It Bq Er EPERM the .Va kern.allowdt .Xr sysctl 2 variable wasn't set. .It Bq Er ENOMEM not enough memory space was available. .El .Sh SEE ALSO .Xr ioctl 2 , .Xr bt 5 , .Xr btrace 8 .Sh HISTORY The .Nm dynamic tracing mechanism first appeared in .Ox 6.7 .