Page MenuHomeFreeBSD

truss: add -t to select which system calls are reported
Needs ReviewPublic

Authored by dteske on Sun, Aug 30, 6:53 PM.

Details

Reviewers
adrian
emaste
fuz
Summary

truss reports every system call a process makes, which for anything
larger than a toy program buries the calls of interest. Add -t, taking
a comma-separated expression naming the system calls to report.

Each term is either an fnmatch(3) pattern matched against the system
call name, or "@group" naming a group of related system calls. A term
prefixed with '!' excludes what it matches rather than including it.
An expression whose terms are all negated subtracts from the set of
every system call; any other expression selects from an empty one.
Terms apply in order and the last one to match a system call decides
whether it is reported.

truss -t @file,@net fetch https://www.freebsd.org/
truss -t '!@memory' make buildworld
truss -t '@desc,!@read,!@write' -p 34
truss -c -t 'readlink*' /bin/ls

Twelve groups are provided to start with: @all, @creds, @desc, @file,
@ipc, @memory, @net, @proc, @read, @signal, @time and @write. These
were derived by working through sys/kern/syscalls.master; the audit
event in that file is too sparse to drive the grouping by itself (316
distinct events over 509 live system calls, 111 of them AUE_NULL), so
the groups are curated, but they are curated as fnmatch patterns rather
than as name lists. A family sharing a naming convention is written as
one pattern -- "extattr_*_file", "__acl_*_fd", "sctp_*" -- so system
calls added later join the right group without further change here.
A group may also name another group as a member, which is how @desc is
built from @read and @write without repeating them. Adding a group is
a member list plus one entry in syscall_groups[].

"truss -t" with no expression prints the groups and exits.

Matching is done against the name truss displays and against that name
with any compatibility or ABI prefix removed, so @file selects
compat11.stat, freebsd32_stat and linux_newstat as well as stat.

A system call excluded by -t is not decoded at all, only counted out,
so the filter also removes the cost of formatting arguments that would
never be printed.

The option letter follows truss on System V Release 4 and SunOS, which
spell this same feature "-t [!]syscall,...", and which truss(1) already
names as its model.

Without -t the behaviour is unchanged.

MFC after: 2 weeks

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 76335
Build 73218: arc lint + arc unit

Event Timeline

Great work! I like it!

usr.bin/truss/main.c
145

This should exit with a nonzero status so that callers doing truss -t $filter where filter ends up unset get a loud failure instead of garbage output.

usr.bin/truss/syscall_filter.c
209
333

Something is buggy with this logic. truss -t "" fails with “empty term in -t” for me, but should just set up no filters.

usr.bin/truss/main.c
145

Good catch. Thanks. I'll change this to return (1);

usr.bin/truss/syscall_filter.c
209

Good catch, I missed that

usr.bin/truss/syscall_filter.c
333

Discussed offline -- we agree this should silently succeed and act as a nop

Other points we discussed to implement:

  1. -t call1,,,,call2 should not produce the empty set error. Just silently ignore empty elements between comma
  2. Because SunOS/Illumos/Solaris have -t [!]syscall[,...] but treat ! differently that we do, we should document in our man-page that ! is for the single comma-separated element only, not a modifier carried-forward to later comma-separated elements
  3. Implement a @none which maps to !@all
  4. Add tests for @none and !@none
  5. Add test for -t ''
  6. Make "truss -t" return 2 so it is unique from errors (that return 1)
usr.bin/truss/main.c
145

Correction. Based on offline discussion, you said you'd like to see return (2); here to make it distinct. I like that idea.

Also worth mentioning, we can prevent a level of astonishment if we issue a warning if a named syscall is unknown.

Also going to make a shot at supporting syscalls by-number, with validation