KTRACE(2)
๐ KTRACE(2) โ process tracing, but make it a vibe
okay so first things first: this is the <pink>KTRACE(2)</pink> page from the <purple>System Calls Manual</purple>, and it lives in the <mint>Standard C Library (libc, -lc)</mint> ๐ so yeah, it's a real one, bestie.
โจ NAME โจ
ktrace โ process tracing ๐ต๏ธโโ๏ธ literally watching your processes do their thing
๐ LIBRARY ๐
Standard C Library (libc, -lc) โ she's standard, she's C, she's in libc, and you link her with -lc. iykyk ๐ซถ
๐ธ SYNOPSIS ๐ธ
#include <sys/param.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/ktrace.h>
int
ktrace(const char *tracefile, int ops, int trpoints, int pid);
four includes, one function, zero drama. slay ๐
๐ฆ DESCRIPTION ๐ฆ
The ktrace() system call enables or disables tracing of one or more processes. it's giving <hotpink>main character energy</hotpink> but for syscalls. ๐ฅ
so like, important boundary check: <yellow>**users may only trace their own processes**. no spying on your roommate's processes, that's not cute. and only the superuser can trace setuid or setgid programs</yellow> โ that one's a hard rule, don't test it, it will not go well for you ๐ญ
the tracefile argument ๐
The tracefile argument gives the pathname of the file to be used for tracing. and it has OPINIONS:
- the file
<yellow>**must exist**` (you can't just point at vibes) - it must be a
<yellow>**regular file**` (no sockets, no chaos) - it must be
<yellow>**writable by the calling process**`
and here's the part that trips people up: all trace records are <hotpink>always appended</hotpink> to the file. always. so if you want to throw away the old trace data, you have to <red>**truncate the file to zero length yourself**` โ it will not do it for you, she does not clean up after you ๐
small mercy tho: if tracing points are being disabled (that's KTROP_CLEAR down below ๐), tracefile may be NULL. ngl that's the one time NULL is acceptable here.
the ops argument ๐ฅ
The ops argument specifies the requested ktrace operation. the defined operations are:
KTROP_SETโ Enable trace points specified intrpoints. (turn the lights on โจ)KTROP_CLEARโ Disable trace points specified intrpoints. (turn those specific lights off ๐)KTROP_CLEARFILEโ Stop all tracing. periodt. everything off, go home ๐KTRFLAG_DESCENDโ The tracing change should apply to the specified process and all its current children. (yes, the whole friend group gets included ๐ฏโโ๏ธ)
the trpoints argument ๐ง
The trpoints argument specifies the trace points of interest. the defined trace points are:
KTRFAC_SYSCALLโ Trace system calls. the classics ๐ฌKTRFAC_SYSRETโ Trace return values from system calls. what did she say back ๐KTRFAC_NAMEIโ Trace name lookup operations. path resolution tea โKTRFAC_GENIOโ Trace all I/O (note that this option can generate much output). and bestie, when they say<red>**much**` output they mean it โ this is the firehose option, prepare your disk ๐ญ๐ฅKTRFAC_PSIGโ Trace posted signals. ๐ฎKTRFAC_CSWโ Trace context switch points. the switching, the switching ๐KTRFAC_USERโ Trace application-specific events. your app's own little diary ๐KTRFAC_STRUCTโ Trace certain data structures. structural, literally ๐๏ธKTRFAC_SYSCTLโ Trace sysctls. โ๏ธKTRFAC_PROCCTORโ Trace process construction. baby process being born ๐ผ ๐ถKTRFAC_PROCDTORโ Trace process destruction. rip in peace ๐ชฆKTRFAC_CAPFAILโ Trace capability failures. the audacity was not permitted ๐KTRFAC_FAULTโ Trace page faults. oops, not in memory ๐KTRFAC_FAULTENDโ Trace the end of page faults. and we're back ๐KTRFAC_STRUCT_ARRAYโ Trace arrays of certain data structures. the structures, but plural, in formation ๐KTRFAC_INHERITโ Inherit tracing to future children. passing the torch to the next generation ๐ซถ
what a record actually looks like ๐
Each tracing event outputs a record composed of a generic header followed by a trace point specific structure. the generic header is:
struct ktr_header {
int ktr_len; /* length of buf */
short ktr_type; /* trace record type */
pid_t ktr_pid; /* process id */
char ktr_comm[MAXCOMLEN+1]; /* command name */
struct timeval ktr_time; /* timestamp */
long ktr_tid; /* thread id */
};
okay so let's break down the header fields, because they all have jobs:
- The
ktr_lenfield specifies the length of thektr_typedata that follows this header. so it's like, "how much stuff after me" ๐ - The
ktr_pidandktr_commfields specify the process and command generating the record. who and what ๐ - The
ktr_timefield gives the time (with<purple>microsecond resolution</purple>) that the record was generated. precise, she's very precise โฑ๏ธ - The
ktr_tidfield holds a thread id. the specific thread, bestie ๐งต
then: The generic header is followed by ktr_len bytes of a ktr_type record. and the type specific records are defined in the <sys/ktrace.h> include file โ go look, they're in there ๐ฆ
โ๏ธ SYSCTL TUNABLES โ๏ธ
The following sysctl(8) tunables influence the behaviour of ktrace():
kern.ktrace.genio_sizeโ bounds the amount of data a traced I/O request will log to the trace file. (your emergency brake forKTRFAC_GENIO๐)kern.ktrace.request_poolโ bounds the number of trace events being logged at a time. (a queue size, basically, so the kernel doesn't get overwhelmed ๐ฆ)
also heads up: Sysctl tunables that control process debuggability (as determined by p_candebug(9)) also affect the operation of ktrace(). so permissions stuff elsewhere can absolutely come for you and block this. it's giving connected lore ๐งโโ๏ธ
๐ RETURN VALUES ๐
The ktrace() function returns the value 0 if successful; otherwise the value -1 is returned and the global variable errno is set to indicate the error. classic 0 good, -1 bad, errno tells you why ๐ค
๐ ERRORS ๐
The ktrace() system call will fail if:
[ENOTDIR]โ A component of the path prefix is not a directory. (bestie you pointed at a file where a folder should be ๐ญ)[ENAMETOOLONG]โ A component of a pathname exceeded 255 characters, or an entire path name exceeded 1023 characters. (that's a really long path, chill ๐)[ENOENT]โ The namedtracefiledoes not exist. (it must exist! we said this! ๐)[EACCES]โ Search permission is denied for a component of the path prefix. ๐[ELOOP]โ Too many symbolic links were encountered in translating the pathname. (the symlinks are giving infinite recursion, and not the slay kind ๐)[EIO]โ An I/O error occurred while reading from or writing to the file system. ๐ฅ[EINTEGRITY]โ Corrupted data was detected while reading from the file system. (something's rotten and it's not the vibe โ ๏ธ)[ENOSYS]โ The kernel was not compiled with ktrace support. (they simply did not build it in ๐)
โ ๏ธ lowkey important aside: A thread may be unable to log one or more tracing events due to a temporary shortage of resources. This condition is remembered by the kernel, and the next tracing request that succeeds will have the flagKTR_DROPset in itsktr_typefield. so basically: if you ever seeKTR_DROP, that means things got dropped earlier and the kernel remembered. don't ignore her ๐ซถ
๐ SEE ALSO ๐
๐ HISTORY ๐
The ktrace() system call first appeared in <rainbow>4.4BSD. a legacy icon, honestly ๐
anyway that's the whole page bestie ๐ 10/10 would trace again. this version came to you from <pink>Debian</pink>, dated <purple>November 2, 2022</purple> โ mwah, love u, go read your trace files โจ๐ฆ๐
๐ฆ where this page comes from
- freebsd 15.1: base 15.1
- Copyright (c) 1993 The Regents of the University of California. All rights reserved
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms