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

Introduction

Show cases

Installation

Different people have different opinions when it comes to how to install a program. Some may prefer using system package manager while others might like downloading a prebuilt binary. But don’t worry, tracexec supports a wide variety of installation methods.

Before installation, you can check the platform support status.

Install via Package Managers

tracexec is packaged in the following distributions.

Packaging status

Arch Linux (And Arch-based distributions)

tracexec is available in extra repository for Arch Linux. You can install it via

sudo pacman -S tracexec

Nix

To try tracexec without system-wide installation, running

nix-shell -p tracexec

will drop you into a shell where tracexec is available.

NixOS

If you are using NixOS, you should already have your preferred way to install packages.

e.g. by adding pkgs.tracexec to environment.systemPackages

Prebuilt Binaries

For stable versions, we release binaries in GitHub Releases.

Currently we offer two flavors of binaries

  • Normal builds that dynamically links most dependencies except libbpf.
  • Fully statically-linked builds which statically links all libraries including glibc.

Install from Source

Please refer to Building from Source for dependencies and feature flags.

To install the current stable version of tracexec. Run

cargo install tracexec --bin tracexec

To install the bleeding-edge main branch git version of tracexec. Run

cargo install --git https://github.com/kxxt/tracexec --bin tracexec

Platform Support

Currently tracexec only supports Linux operating system. Because the core of tracexec is implemented via ptrace, seccomp-bpf and eBPF, it is difficult to port to Windows, MacOS or other operating systems. (Well, technically speaking, ptrace itself is enough for initializing a port to other operating systems, but ptrace without seccomp-bpf is painfully slow.)

Architecture Support Status

Currently we support the following three architectures. You are welcome to submit PR for supporting more architectures.

ArchitectureOperating Systemptrace backendptrace backend
w/ seccomp-bpf
eBPF backend
x86_64Linux
aarch64Linux
riscv64*Linux

*: for riscv64, some kernel versions has bugs in the ptrace implementation that would cause tracexec to display some information as errors. See this strace issue and the kernel mailing list discussion for more details if you got errors when using tracexec on riscv64.

Linux Kernel Support Status

Kernel Versionptrace backendeBPF backendComments
< 5.3❌ (Need PTRACE_GET_SYSCALL_INFO)Seriously, upgrade your kernel!!!
>= 5.3,< 5.17❌ (Need bpf_loop)
>=5.17
>= 6.2
(LTS) >=6.6.64, <6.6.70❌ fail due to kernel regressionKernel regression caught by our CI

Build from Source

To build tracexec from source, the following dependencies are needed:

  • A working rust compiler and cargo.
    • Refer to package.rust-version in Cargo.toml for MSRV.
  • libbpf: if not using vendored-libbpf
  • zlib: if not using vendored-zlib
  • libelf: if not using vendored-libbpf
  • libseccomp: For seccomp-bpf.
  • If any library vendoring feature is enabled:
    • build-essential autopoint gettext for Debian based distros
    • base-devel for Arch Linux
  • clang for compiling eBPF program.

Library Linkage

By default, we dynamically link to libseccomp because most distros ship it out of box. In order to statically link to libseccomp, please set LIBSECCOMP_LINK_TYPE to static and set LIBSECCOMP_LIB_PATH to the path of the directory containing libseccomp.a.

To control whether or not to dynamically link to libbpf, libelf and zlib, consult the next Feature Flags section.

Feature Flags

  • recommended: This enables the recommended functionalities of tracexec
    • ebpf(experimental): eBPF backend that doesn’t use ptrace and could be used for system wide tracing
  • ebpf-debug: Not meant for end users. This flag enables debug logging to /sys/kernel/debug/tracing/trace_pipe and some debug checks.
  • static: Statically link libelf, zlib and libbpf.
  • vendored: Vendoring libelf, zlib and libbpf, implies static.
  • vendored-libbpf: Vendoring libbpf and statically link to it.

By default, we enable the recommended and vendored-libbpf features. This means that we are dynamically linking zlib and libelf but statically linking libbpf. This choice is made because zlib and libelf are usually installed on most systems but libbpf is usually not.

To dynamically link to libbpf, turn off default features and enable recommended feature:

cargo build --release --no-default-features -F recommended

Features

Stable Features

Experimental Features

Tutorials

Debugging a basic build problem

Use tracexec as debugger launcher

Catching FD leaks

Comparison with other tools

There are many existing tools for tracing exec syscalls when I start to create tracexec. However, none of them suit my use case well.

This chapter provides a comparison between tracexec and those tools. I hope this chapter will provide readers the knowledge about choosing the best tool for their use cases.

We can roughly divide the tools into three categories by how exec tracing is implemented. (Tracexec supports multiple ways for tracing exec)

tooleBPFLoadable Kernel Moduleptrace
tracexec
strace
execsnoop (bcc)
execsnoop (bpftrace)
execsnoop-nd.stp

Comparison with execsnoop(bcc)

This article compares tracexec with the latest commit of execsnoop at the time of writing. Feel free to improve it if you found anything outdated.

There are two execsnoop implementations in bcc, one implemented with Python, another one implemented with libbpf. Here we will compare with the Python implementation as it supports more features at the time of writing.

Shortcomings of execsnoop(bcc)

Default Limits are Too Limited

By default, execsnoop can only trace up to 20 arguments per exec event, which is too limited to trace complex compiler invocations by various build systems. It can be raised using --max-args argument.

And execsnoop hardcodes a very low limit(128) for the length of each argument, if any argument exceeds this limit, it is silently truncated, resulting in wrong output without any notification to the user.

Cannot Show ARGV[0]

execsnoop shows filename in the place of the first argument(argv[0]) and discards the real argv[0]. Most of the time this is not important because argv[0] is the filename or the basename of the filename.

However, sometimes argv[0] and filename are different and this difference plays an important role on how the program behaves. For example, multi-call binaries like busybox can act as different commands depending on argv[0].

Cannot Show Environment Variables

Sometimes, environment variables play a vital role in program execution. execsnoop doesn’t show them at all.

Cannot Copy-Paste-Execute

A handy feature of tracexec is to copy the shell escaped command line to clipboard, which you can directly paste into another terminal and hit enter to execute it.

But as for execsnoop. It doesn’t even quote the arguments by default, making it hard to distinguish the boundary between arguments. Even if -q/--quote is used, there is still a long way to copy-paste-execute because it does not perform shell escaping. Even if it performs shell-escaping in the future. Without the environment variables, the command may also not work.

Missing features in tracexec compared with execsnoop(bcc)

execsnoop supports tracing processes under a cgroups path and limit tracing to a specific UID.

execsnoop (bpftrace)

strace

FAQ

Developer Guide