Hi, Debugging some code paths is complex: for example, unveil(2) code is involved inside VFS, and using DEBUG_UNVEIL means that the kernel is spamming printf() for all processes using unveil(2) (a lot of processes) instead of just the interested cases I want to follow.
So I cooked the following diff to add a KTRLOG() facility to be able to replace printf()-like debugging with a more process-limited method. >From ktrace(2) point of vue, it adds a new KTR_LOG record type, which is just a string. And it adds a function ktrlog(struct proc *, const char *, ...) which is a printf-like function. The following diff includes unveil(2) conversion from printf-debug message to KTRLOG-debug message. kdump output (LOG entries are new): 10388 a.out CALL unveil(0x149833ac,0x149833c3) 10388 a.out STRU flags="rx" 10388 a.out NAMI "/usr/bin/id" 10388 a.out LOG "added name id underneath vnode 0xd580c9a0" 10388 a.out LOG "unveil: added name id beneath restricted vnode 0xd580c9a0, uvcount 6" 10388 a.out RET unveil 0 10388 a.out CALL unveil(0,0) 10388 a.out RET unveil 0 10388 a.out CALL kbind(0xcf7e4724,12,0x35c420ed57689eb8) 10388 a.out RET kbind 0 10388 a.out CALL stat(0x149833ba,0xcf7e47a0) 10388 a.out NAMI "/usr/bin" 10388 a.out LOG "unveil: component directory match for vnode 0xd58537f8" 10388 a.out LOG "unveil: no match for vnode 0xd580c9a0" 10388 a.out LOG "unveil: matched \"bin\" underneath/at vnode 0xd58537f8" 10388 a.out STRU struct stat { dev=3, ino=77952, mode=drwxr-xr-x , nlink=2, uid=0<"root">, gid=0<"wheel">, rdev=319024, atime=1641543393<"Jan 7 09:16:33 2022">.860011379, mtime=1641542018<"Jan 7 08:53:38 2022">.406865980, ctime=1641542018<"Jan 7 08:53:38 2022">.406865980, size=5632, blocks=12, blksize=16384, flags=0x0, gen=0x0 } 10388 a.out RET stat 0 Additionnally, it permits to properly link the message string with the syscall involved and the process code path. Does it might be interesting for people ? or should I just keep it locally ? Thanks. -- Sebastien Marie diff aab2d6589bc1ae2859ab3800e0ad61fbd5f87fd1 598aa538be37ceddf77c1c352553462362219e2c blob - 23b2af5c88dfbc4858fe14718beed80c0ebb0d48 blob + 23fd09812f14fedc59f0a971507715e21c3b9441 --- sys/kern/kern_ktrace.c +++ sys/kern/kern_ktrace.c @@ -405,6 +405,34 @@ ktrpledge(struct proc *p, int error, uint64_t code, in atomic_clearbits_int(&p->p_flag, P_INKTR); } +void +ktrlog(struct proc *p, const char *fmt, ...) +{ + struct ktr_header kth; + char buf[1024]; + int n; + va_list ap; + + atomic_setbits_int(&p->p_flag, P_INKTR); + ktrinitheader(&kth, p, KTR_LOG); + + va_start(ap, fmt); + n = vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + if (n >= sizeof(buf)) { + buf[sizeof(buf) - 4] = '.'; + buf[sizeof(buf) - 3] = '.'; + buf[sizeof(buf) - 2] = '.'; + buf[sizeof(buf) - 1] = '\0'; + } + + KERNEL_LOCK(); + ktrwrite(p, &kth, buf, strlen(buf)); + KERNEL_UNLOCK(); + atomic_clearbits_int(&p->p_flag, P_INKTR); +} + /* Interface and common routines */ int blob - 801c210c113666aacf826b52a6a430e334f0a09d blob + 32d3284ca932ec7a504647dd424502ea8a0a1f7b --- sys/kern/kern_unveil.c +++ sys/kern/kern_unveil.c @@ -55,7 +55,9 @@ struct unveil { u_char uv_flags; }; -/* #define DEBUG_UNVEIL */ +#ifdef KTRACE +/*#define DEBUG_UNVEIL */ +#endif #define UNVEIL_MAX_VNODES 128 #define UNVEIL_MAX_NAMES 128 @@ -104,7 +106,7 @@ unveil_delete_names(struct unveil *uv) } rw_exit_write(&uv->uv_lock); #ifdef DEBUG_UNVEIL - printf("deleted %d names\n", ret); + KTRLOG(curproc, "deleted %d names", ret); #endif return ret; } @@ -121,7 +123,7 @@ unveil_add_name_unlocked(struct unveil *uv, char *name return 0; } #ifdef DEBUG_UNVEIL - printf("added name %s underneath vnode %p\n", name, uv->uv_vp); + KTRLOG(curproc, "added name %s underneath vnode %p", name, uv->uv_vp); #endif return 1; } @@ -145,7 +147,7 @@ unveil_namelookup(struct unveil *uv, char *name) rw_enter_read(&uv->uv_lock); #ifdef DEBUG_UNVEIL - printf("unveil_namelookup: looking up name %s (%p) in vnode %p\n", + KTRLOG(curproc, "unveil_namelookup: looking up name %s (%p) in vnode %p", name, name, uv->uv_vp); #endif @@ -160,10 +162,10 @@ unveil_namelookup(struct unveil *uv, char *name) #ifdef DEBUG_UNVEIL if (ret == NULL) - printf("unveil_namelookup: no match for name %s in vnode %p\n", + KTRLOG(curproc, "unveil_namelookup: no match for name %s in vnode %p", name, uv->uv_vp); else - printf("unveil_namelookup: matched name %s in vnode %p\n", + KTRLOG(curproc, "unveil_namelookup: matched name %s in vnode %p", name, uv->uv_vp); #endif return ret; @@ -182,9 +184,8 @@ unveil_destroy(struct process *ps) if (vp != NULL) { vp->v_uvcount--; #ifdef DEBUG_UNVEIL - printf("unveil: %s(%d): removing vnode %p uvcount %d " - "in position %ld\n", - ps->ps_comm, ps->ps_pid, vp, vp->v_uvcount, i); + KTRLOG(curproc, "unveil: removing vnode %p uvcount %d" + " in position %ld", vp, vp->v_uvcount, i); #endif vrele(vp); } @@ -291,7 +292,9 @@ unveil_find_cover(struct vnode *dp, struct proc *p) * This corner case should not happen because * we have not set LOCKPARENT in the flags */ - printf("vnode %p PDIRUNLOCK on error\n", vp); +#ifdef DEBUG_UNVEIL + KTRLOG(p, "vnode %p PDIRUNLOCK on error", vp); +#endif vrele(vp); } break; @@ -373,7 +376,7 @@ unveil_setflags(u_char *flags, u_char nflags) #if 0 if (((~(*flags)) & nflags) != 0) { #ifdef DEBUG_UNVEIL - printf("Flags escalation %llX -> %llX\n", *flags, nflags); + KTRLOG(curproc, "Flags escalation %llX -> %llX", *flags, nflags); #endif return 1; } @@ -466,9 +469,8 @@ unveil_add(struct proc *p, struct nameidata *ndp, cons */ if (directory_add) { #ifdef DEBUG_UNVEIL - printf("unveil: %s(%d): updating directory vnode %p" - " to unrestricted uvcount %d\n", - pr->ps_comm, pr->ps_pid, vp, vp->v_uvcount); + KTRLOG(p, "unveil: updating directory vnode %p" + " to unrestricted uvcount %d", vp, vp->v_uvcount); #endif if (!unveil_setflags(&uv->uv_flags, flags)) ret = EPERM; @@ -486,9 +488,8 @@ unveil_add(struct proc *p, struct nameidata *ndp, cons if ((tname = unveil_namelookup(uv, ndp->ni_cnd.cn_nameptr)) != NULL) { #ifdef DEBUG_UNVEIL - printf("unveil: %s(%d): changing flags for %s" - "in vnode %p, uvcount %d\n", - pr->ps_comm, pr->ps_pid, tname->un_name, vp, + KTRLOG(p, "unveil: changing flags for %s in vnode %p," + " uvcount %d", tname->un_name, vp, vp->v_uvcount); #endif if (!unveil_setflags(&tname->un_flags, flags)) @@ -517,9 +518,8 @@ unveil_add(struct proc *p, struct nameidata *ndp, cons uv->uv_flags = flags; ret = 0; #ifdef DEBUG_UNVEIL - printf("unveil: %s(%d): added unrestricted directory vnode %p" - ", uvcount %d\n", - pr->ps_comm, pr->ps_pid, vp, vp->v_uvcount); + KTRLOG(p, "unveil: added unrestricted directory vnode %p" + ", uvcount %d", vp, vp->v_uvcount); #endif goto done; } @@ -529,9 +529,8 @@ unveil_add(struct proc *p, struct nameidata *ndp, cons ret = 0; #ifdef DEBUG_UNVEIL - printf("unveil: %s(%d): added name %s beneath %s vnode %p," - " uvcount %d\n", - pr->ps_comm, pr->ps_pid, ndp->ni_cnd.cn_nameptr, + KTRLOG(p, "unveil: added name %s beneath %s vnode %p, uvcount %d", + ndp->ni_cnd.cn_nameptr, uv->uv_flags ? "unrestricted" : "restricted", vp, vp->v_uvcount); #endif @@ -549,14 +548,14 @@ unveil_flagmatch(struct nameidata *ni, u_char flags) { if (flags == 0) { #ifdef DEBUG_UNVEIL - printf("All operations forbidden for 0 flags\n"); + KTRLOG(curproc, "All operations forbidden for 0 flags"); #endif return 0; } if (ni->ni_unveil & UNVEIL_READ) { if ((flags & UNVEIL_READ) == 0) { #ifdef DEBUG_UNVEIL - printf("unveil lacks UNVEIL_READ\n"); + KTRLOG(curproc, "unveil lacks UNVEIL_READ"); #endif return 0; } @@ -564,7 +563,7 @@ unveil_flagmatch(struct nameidata *ni, u_char flags) if (ni->ni_unveil & UNVEIL_WRITE) { if ((flags & UNVEIL_WRITE) == 0) { #ifdef DEBUG_UNVEIL - printf("unveil lacks UNVEIL_WRITE\n"); + KTRLOG(curproc, "unveil lacks UNVEIL_WRITE"); #endif return 0; } @@ -572,7 +571,7 @@ unveil_flagmatch(struct nameidata *ni, u_char flags) if (ni->ni_unveil & UNVEIL_EXEC) { if ((flags & UNVEIL_EXEC) == 0) { #ifdef DEBUG_UNVEIL - printf("unveil lacks UNVEIL_EXEC\n"); + KTRLOG(curproc, "unveil lacks UNVEIL_EXEC"); #endif return 0; } @@ -580,7 +579,7 @@ unveil_flagmatch(struct nameidata *ni, u_char flags) if (ni->ni_unveil & UNVEIL_CREATE) { if ((flags & UNVEIL_CREATE) == 0) { #ifdef DEBUG_UNVEIL - printf("unveil lacks UNVEIL_CREATE\n"); + KTRLOG(curproc, "unveil lacks UNVEIL_CREATE"); #endif return 0; } @@ -640,8 +639,7 @@ unveil_start_relative(struct proc *p, struct nameidata */ if (uv) { #ifdef DEBUG_UNVEIL - printf("unveil: %s(%d): relative unveil at %p matches", - pr->ps_comm, pr->ps_pid, uv); + KTRLOG(p, "unveil: relative unveil at %p matches", uv); #endif ni->ni_unveil_match = uv; } @@ -677,8 +675,7 @@ unveil_check_component(struct proc *p, struct nameidat /* update match */ ni->ni_unveil_match = uv; #ifdef DEBUG_UNVEIL - printf("unveil: %s(%d): component directory match for " - "vnode %p\n", pr->ps_comm, pr->ps_pid, dp); + KTRLOG(p, "unveil: component directory match for vnode %p", dp); #endif } } @@ -699,8 +696,7 @@ unveil_check_final(struct proc *p, struct nameidata *n if (ni->ni_cnd.cn_flags & BYPASSUNVEIL) { #ifdef DEBUG_UNVEIL - printf("unveil: %s(%d): BYPASSUNVEIL.\n", - pr->ps_comm, pr->ps_pid); + KTRLOG(p, "unveil: BYPASSUNVEIL"); #endif return (0); } @@ -710,16 +706,14 @@ unveil_check_final(struct proc *p, struct nameidata *n uv = unveil_lookup(ni->ni_vp, pr, NULL); if (uv == NULL) { #ifdef DEBUG_UNVEIL - printf("unveil: %s(%d) no match for vnode %p\n", - pr->ps_comm, pr->ps_pid, ni->ni_vp); + KTRLOG(p, "unveil: no match for vnode %p", ni->ni_vp); #endif goto done; } if (!unveil_flagmatch(ni, uv->uv_flags)) { #ifdef DEBUG_UNVEIL - printf("unveil: %s(%d) flag mismatch for directory" - " vnode %p\n", - pr->ps_comm, pr->ps_pid, ni->ni_vp); + KTRLOG(p, "unveil: flag mismatch for directory" + " vnode %p", ni->ni_vp); #endif pr->ps_acflag |= AUNVEIL; if (uv->uv_flags & UNVEIL_USERSET) @@ -730,9 +724,8 @@ unveil_check_final(struct proc *p, struct nameidata *n } /* directory and flags match, success */ #ifdef DEBUG_UNVEIL - printf("unveil: %s(%d): matched directory \"%s\" at vnode %p\n", - pr->ps_comm, pr->ps_pid, ni->ni_cnd.cn_nameptr, - uv->uv_vp); + KTRLOG(p, "unveil: matched directory \"%s\" at vnode %p", + ni->ni_cnd.cn_nameptr, uv->uv_vp); #endif return (0); } @@ -741,26 +734,22 @@ unveil_check_final(struct proc *p, struct nameidata *n uv = unveil_lookup(ni->ni_dvp, pr, NULL); if (uv == NULL) { #ifdef DEBUG_UNVEIL - printf("unveil: %s(%d) no match for directory vnode %p\n", - pr->ps_comm, pr->ps_pid, ni->ni_dvp); + KTRLOG(p, "unveil: no match for directory vnode %p", + ni->ni_dvp); #endif goto done; } if ((tname = unveil_namelookup(uv, ni->ni_cnd.cn_nameptr)) == NULL) { #ifdef DEBUG_UNVEIL - printf("unveil: %s(%d) no match for terminal '%s' in " - "directory vnode %p\n", - pr->ps_comm, pr->ps_pid, - ni->ni_cnd.cn_nameptr, ni->ni_dvp); + KTRLOG(p, "unveil: no match for terminal '%s' in " + "directory vnode %p", ni->ni_cnd.cn_nameptr, ni->ni_dvp); #endif /* no specific name, so check unveil directory flags */ if (!unveil_flagmatch(ni, uv->uv_flags)) { #ifdef DEBUG_UNVEIL - printf("unveil: %s(%d) terminal " - "'%s' flags mismatch in directory " - "vnode %p\n", - pr->ps_comm, pr->ps_pid, - ni->ni_cnd.cn_nameptr, ni->ni_dvp); + KTRLOG(p, "unveil: terminal '%s' flags mismatch in " + "directory vnode %p", ni->ni_cnd.cn_nameptr, + ni->ni_dvp); #endif /* * If dir has user set restrictions fail with @@ -769,6 +758,10 @@ unveil_check_final(struct proc *p, struct nameidata *n */ if (uv->uv_flags & UNVEIL_USERSET) { pr->ps_acflag |= AUNVEIL; +#ifdef DEBUG_UNVEIL + KTRLOG(p, "unveil: terminal flags mismatch" + " in directory"); +#endif return EACCES; } /* start backtrack from this node */ @@ -777,25 +770,23 @@ unveil_check_final(struct proc *p, struct nameidata *n } /* directory flags match, success */ #ifdef DEBUG_UNVEIL - printf("unveil: %s(%d): matched \"%s\" underneath vnode %p\n", - pr->ps_comm, pr->ps_pid, ni->ni_cnd.cn_nameptr, - uv->uv_vp); + KTRLOG(p, "unveil: matched \"%s\" underneath vnode %p", + ni->ni_cnd.cn_nameptr, uv->uv_vp); #endif return (0); } if (!unveil_flagmatch(ni, tname->un_flags)) { /* do flags match for matched name */ #ifdef DEBUG_UNVEIL - printf("unveil: %s(%d) flag mismatch for terminal '%s'\n", - pr->ps_comm, pr->ps_pid, tname->un_name); + KTRLOG(p, "unveil: flag mismatch for terminal '%s'", + tname->un_name); #endif pr->ps_acflag |= AUNVEIL; return EACCES; } /* name and flags match. success */ #ifdef DEBUG_UNVEIL - printf("unveil: %s(%d) matched terminal '%s'\n", - pr->ps_comm, pr->ps_pid, tname->un_name); + KTRLOG(p, "unveil: matched terminal '%s'", tname->un_name); #endif return (0); @@ -807,30 +798,32 @@ done: for (uv = ni->ni_unveil_match; uv != NULL; uv = nuv) { if (unveil_flagmatch(ni, uv->uv_flags)) { #ifdef DEBUG_UNVEIL - printf("unveil: %s(%d): matched \"%s\" underneath/at " - "vnode %p\n", pr->ps_comm, pr->ps_pid, - ni->ni_cnd.cn_nameptr, uv->uv_vp); + KTRLOG(p, "unveil: matched \"%s\" underneath/at " + "vnode %p", ni->ni_cnd.cn_nameptr, uv->uv_vp); #endif return (0); } /* if node has any flags set then this is an access violation */ if (uv->uv_flags & UNVEIL_USERSET) { #ifdef DEBUG_UNVEIL - printf("unveil: %s(%d) flag mismatch for vnode %p\n", - pr->ps_comm, pr->ps_pid, uv->uv_vp); + KTRLOG(p, "unveil: flag mismatch for vnode %p", + uv->uv_vp); #endif pr->ps_acflag |= AUNVEIL; return EACCES; } #ifdef DEBUG_UNVEIL - printf("unveil: %s(%d) check cover for vnode %p, uv_cover %zd\n", - pr->ps_comm, pr->ps_pid, uv->uv_vp, uv->uv_cover); + KTRLOG(p, "unveil: check cover for vnode %p, uv_cover %zd", + uv->uv_vp, uv->uv_cover); #endif nuv = unveil_covered(uv, uv->uv_vp, p); if (nuv == uv) break; } pr->ps_acflag |= AUNVEIL; +#ifdef DEBUG_UNVEIL + KTRLOG(p, "unveil: no cover"); +#endif return ENOENT; } @@ -850,7 +843,7 @@ unveil_removevnode(struct vnode *vp) return; #ifdef DEBUG_UNVEIL - printf("unveil_removevnode found vnode %p with count %d\n", + KTRLOG(curproc, "unveil_removevnode: found vnode %p with count %d", vp, vp->v_uvcount); #endif vref(vp); /* make sure it is held till we are done */ @@ -863,7 +856,7 @@ unveil_removevnode(struct vnode *vp) uv->uv_vp = NULL; uv->uv_flags = 0; #ifdef DEBUG_UNVEIL - printf("unveil_removevnode vnode %p now count %d\n", + KTRLOG(curproc, "unveil_removevnode: vnode %p now count %d", vp, vp->v_uvcount); #endif if (vp->v_uvcount > 0) { blob - f500e552234a66e9ae1adeea57649beb8e035df0 blob + 9cfd2fc631f06fb6825f4c836b8d3e8a704f7738 --- sys/sys/ktrace.h +++ sys/sys/ktrace.h @@ -164,6 +164,13 @@ struct ktr_pledge { }; /* + * KTR_LOG - log record + */ +#define KTR_LOG 13 + /* record contains log message */ + + +/* * kernel trace points (in ps_traceflag) */ #define KTRFAC_MASK 0x00ffffff @@ -177,6 +184,7 @@ struct ktr_pledge { #define KTRFAC_EXECARGS (1<<KTR_EXECARGS) #define KTRFAC_EXECENV (1<<KTR_EXECENV) #define KTRFAC_PLEDGE (1<<KTR_PLEDGE) +#define KTRFAC_LOG (1<<KTR_LOG) /* * trace flags (also in ps_traceflag) @@ -201,6 +209,13 @@ __END_DECLS #define KTRPOINT(p, type) \ ((p)->p_p->ps_traceflag & (1<<(type)) && ((p)->p_flag & P_INKTR) == 0) +#define KTRLOG(p, ...) \ + do { \ + struct proc *_p = (p); \ + if (KTRPOINT(_p, KTR_LOG)) \ + ktrlog(_p, __VA_ARGS__); \ + } while(0) + void ktrgenio(struct proc *, int, enum uio_rw, struct iovec *, ssize_t); void ktrnamei(struct proc *, char *); void ktrpsig(struct proc *, int, sig_t, int, int, siginfo_t *); @@ -209,6 +224,8 @@ void ktrsysret(struct proc *, register_t, int, const r int ktruser(struct proc *, const char *, const void *, size_t); void ktrexec(struct proc *, int, const char *, ssize_t); void ktrpledge(struct proc *, int, uint64_t, int); +void ktrlog(struct proc *, const char *, ...) + __attribute__((__format__(__kprintf__,2,3))); void ktrcleartrace(struct process *); void ktrsettrace(struct process *, int, struct vnode *, struct ucred *); blob - 9f74e86eb5bd2b14bafe754e972494a569422e71 blob + 9b314a91cf745b9b13ec9b38214aaf0c9db375f4 --- usr.bin/kdump/kdump.1 +++ usr.bin/kdump/kdump.1 @@ -100,7 +100,7 @@ If both options are specified, display timestamps rela .It Fl t Ar trstr Select which tracepoints to display. The argument can contain one or more of the letters -.Cm cinpstuxX+ . +.Cm cilnpstuxX+ . See the .Fl t option of blob - c6e4f1786adfbe7202eb7ca6bbcd5f6ff8dbe368 blob + 5b604c1c8de56fd7ff48e02e93d9744d35f1bcc1 --- usr.bin/kdump/kdump.c +++ usr.bin/kdump/kdump.c @@ -130,6 +130,7 @@ static void ktrsysret(struct ktr_sysret *, size_t); static void ktruser(struct ktr_user *, size_t); static void ktrexec(const char*, size_t); static void ktrpledge(struct ktr_pledge *, size_t); +static void ktrlog(const char *, size_t); static void usage(void); static void ioctldecode(int); static void ptracedecode(int); @@ -293,6 +294,9 @@ main(int argc, char *argv[]) case KTR_PLEDGE: ktrpledge(m, ktrlen); break; + case KTR_LOG: + ktrlog(m, ktrlen); + break; default: printf("\n"); break; @@ -353,6 +357,9 @@ dumpheader(struct ktr_header *kth) case KTR_PLEDGE: type = "PLDG"; break; + case KTR_LOG: + type = "LOG "; + break; default: /* htobe32() not guaranteed to work as case label */ if (kth->ktr_type == htobe32(KTR_START)) { @@ -1440,6 +1447,12 @@ ktrpledge(struct ktr_pledge *pledge, size_t len) } static void +ktrlog(const char *cp, size_t len) +{ + showbufc(basecol, (unsigned char *)cp, len, VIS_DQ | VIS_TAB | VIS_NL); +} + +static void usage(void) { blob - 6b470a45c7508bd3bb2d5e7374f4ad945105a5a9 blob + 9c89d73c2c14fe00ecdc5db26781f1be788d73f2 --- usr.bin/ktrace/ktrace.1 +++ usr.bin/ktrace/ktrace.1 @@ -123,6 +123,8 @@ are enabled. trace system calls .It Cm i trace I/O +.It Cm l +trace kernel log messages .It Cm n trace namei translations .It Cm p blob - 19dc4dbea02a87fe5c4e135578a64176665ea513 blob + 9da425d2404a07133372cfc9349c58bfdeeac98b --- usr.bin/ktrace/ktrace.h +++ usr.bin/ktrace/ktrace.h @@ -32,7 +32,8 @@ #define DEF_POINTS (KTRFAC_SYSCALL | KTRFAC_SYSRET | KTRFAC_NAMEI | \ KTRFAC_GENIO | KTRFAC_PSIG | KTRFAC_STRUCT | \ - KTRFAC_USER | KTRFAC_EXECARGS | KTRFAC_PLEDGE) + KTRFAC_USER | KTRFAC_EXECARGS | KTRFAC_PLEDGE | \ + KTRFAC_LOG) /* any KTRFAC_* not included in DEF_POINTS should be added here */ #define ALL_POINTS (DEF_POINTS | KTRFAC_EXECENV) blob - 55717db6f650fefeb407eb8a7f1920ceb90af915 blob + cdb73698d4dff7f991ae3f96cc5f058ff8c6770a --- usr.bin/ktrace/ltrace.1 +++ usr.bin/ktrace/ltrace.1 @@ -111,6 +111,8 @@ The following table equates the letters with the trace trace system calls .It Cm i trace I/O +.It Cm l +trace kernel log messages .It Cm n trace namei translations .It Cm p blob - cfc23041cd0ebd225a4f3bf6c492c8e67b30fc07 blob + 4484c2d41ac6d5d1637942552de5f8929b5fcc1c --- usr.bin/ktrace/subr.c +++ usr.bin/ktrace/subr.c @@ -56,6 +56,9 @@ getpoints(const char *s, int defpoints) case 'i': facs |= KTRFAC_GENIO; break; + case 'l': + facs |= KTRFAC_LOG; + break; case 'n': facs |= KTRFAC_NAMEI; break;