Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Log Frontend

Logging is the most simple frontend for tracexec. This frontend simply logs exec events to the terminal or a file.

To use the log frontend,

By default, the log frontend shows the filename, argv and diff of environment variables, along with basic information like PID, comm before exec and syscall result.

Log Format

This section introduces the UI elements in the log lines. For example, let’s simply run ls with a new environment variable:

Basic Elements

tracexec log -- env A=B ls

As shown in the output,

  1. The tracer forks and executes /usr/bin/env, with our supplied command line arguments.
    • The exec syscall is successful so the pid at the start of the line is in green color.
    • The comm of the original process is tracer before exec.
  2. /usr/bin/env tried to execute ls program from paths listed in the PATH environment variable.
    • The first few attempts failed because ls program is not found in the attempted directory. The return value -2 is displayed at the end of the line with a user-friendly error message. The pid at the start of the line is displayed in yellow color, meaning a usually non-fatal error occurred.
    • Since we specified A=B in the commandline, env adds this environment variable when executing ls. tracexec shows this added environment variable in green color with a plus sign, indicating it is a new env var.
  3. At last, /usr/bin/env successfully executed /usr/bin/ls and the output from ls is shown.

Timestamp

By default, tracexec does not show the timestamp for the events. Use --timestamp to enable it.

For example:

tracexec log --timestamp -- env ls /

It is possible to customize the format of the timestamp with --inline-timestamp-format <INLINE_TIMESTAMP_FORMAT>. See https://docs.rs/chrono/latest/chrono/format/strftime/index.html for available variables that can be used in the format string.

Verbosity of Environment Variables

By default, tracexec only outputs the diff of environment variables against the initial environment.

To increase the verbosity to show all environment variables, use --show-env. e.g.

tracexec log --show-env -- ls

To hide the environment variables entirely, use --no-show-env.

Reconstruct the Shell Commandline

A handy feature of tracexec is to show the equivalent shell commandlines of the exec events. This feature makes it easy to reproduce the exec events in a shell.

For example:

tracexec log --show-cmdline -- env -u LANG A=B ls

In this example, we use -u LANG to remove the LANG environment variable and A=B to set A env to B for the ls command. tracexec shows the equivalent shell commandline of the successful execution as env -a ls -u LANG A=B /usr/bin/ls, which could be directly copy-and-pasted into a bash shell.

File Descriptor Tracking

File descriptors are inherited during exec unless the file descriptor is marked with O_CLOEXEC. Bugs or even security vulnerabilities may occur if a program forgets to close file descriptors after fork and before exec. However, sometimes it is normal to keep some file descriptors open in order to pass them to the child process.

tracexec tracks the file descriptors used during exec and shows a diff of file descriptors by default.

In the following example, we run cat with stdin closed and stdout redirected to /dev/null and a new file descriptor of /dev/random.

tracexec log -- bash -c "cat <&- > /dev/null 4</dev/random"

tracexec shows the file descriptor diff with three entries.

  • closed: stdin in red color for the closed stdin.
  • stdout="/dev/null" in yellow color, meaning the stdout fd is modified and the current value is /dev/null.
  • 4="/dev/random" in green color, indicating a new fd numbered 4 pointing to /dev/random.

By default, tracexec hides the file descriptors marked O_CLOEXEC that will be closed upon exec. To show such file descriptors, use --no-hide-cloexec-fds option. As demonstrated in the following example, a python script opened a file descriptor with O_CLOEXEC, which gets closed when executing the shell. tracexec shows the file descriptor in red color as cloexec: 3="/".

Log Output Destination

By default, the log frontend outputs to stderr.

To output to stdout, use --output - or -o- (e.g. target/debug/tracexec log -o- -- ls). To output to a file, use --output <PATH> where <PATH> is the path to the file for output. tracexec will truncate the file if it already exists.

(EXPERIMENTAL) Reconstruct Shell Commandline with File Descriptors

Previously, we showed how to reconstruct shell commandlines and track inherited file descriptors. We can combine them to reconstruct a full shell commandline with the file descriptors.

To reconstruct the commandline with stdio descriptors, use --stdio-in-cmdline:

tracexec log --show-cmdline --stdio-in-cmdline -- bash -c "cat <&- > /dev/null 4</dev/random"

To reconstruct the commandline with all file descriptors, use --fd-in-cmdline:

tracexec log --show-cmdline --fd-in-cmdline -- bash -c "cat <&- > /dev/null 4</dev/random"

This feature is currently experimental. It may produce inaccurate command lines. For example,

  • in the above example, the reconstructed cmdline shows FD 4 as both readable and writable, but actually we only used it as an input file descriptor.
  • Shells like zsh have limit on the file descriptor number that could be used in the cmdline. Thus the reconstructed cmdline may not work in some shells. For instance,
    • tracexec log -- bash -c "ls 114514</dev/null" succeeds,
    • but tracexec log -- zsh -c "ls 114514</dev/null" failed with ls: cannot access '114514': No such file or directory