Breakpoints
tracexec supports setting breakpoints at exec syscall enter/exit stops, which enables you to pause programs before they start to execute user-space code.
This feature is only available for the ptrace backend.
Why
You might be wondering why such a feature is useful.
It is mainly because of a limitation of the ptrace(2) API.
A single tracee can only have one tracer at any time.
As a result, debuggers like gdb cannot be used on processes
traced by tracexec.
This feature provides a way to hand over processes traced by tracexec to other debuggers. For example, you can stop a program launched deep inside a shell script and attach gdb to it, with its environment, working directory and pipes already set up.
Breakpoint Stops
There are two places where you can set a breakpoint:
sysenter: right before the exec syscall. The process still has its old program image.sysexit: right after the exec syscall. If the exec succeeded, the new program is loaded but has not started running user-space code yet.
Breakpoint Patterns
A breakpoint pattern decides which exec calls to stop at. There are three kinds of patterns:
| Pattern | When it matches | Example |
|---|---|---|
in-filename | The filename contains the given string. | in-filename:/my-program |
exact-filename | The filename is exactly the given string. | exact-filename:./my-program |
argv-regex | The arguments, joined by spaces, match the regular expression. | argv-regex:^my-program --verbose( |$) |
The filename patterns match the filename recorded by tracexec. The filename is typically the
exact value used in execve syscall or the resolved path of the value used in execveat syscall.
For argv-regex, the arguments include argv[0] and are joined without any quoting or escaping.
For example, ["echo", "hello world"] becomes echo hello world.
The regex can match anywhere in that string; use ^ and $ if you want to match the whole string.
Setting Breakpoints from the Command Line
Use -b (or --add-breakpoint) to add a breakpoint before tracing starts.
The format is <breakpoint-stop>:<pattern-kind>:<pattern>.
For example, to stop whenever a program whose filename contains /my-program is executed:
tracexec tui -b 'sysexit:in-filename:/my-program' -- bash
You can now run ./my-program in the terminal pane, either directly or through a script.
It will stop before it starts running, and tracexec will show a hit at the bottom of the screen.
You can use -b multiple times to add more breakpoints:
tracexec tui \
-b 'sysexit:exact-filename:./a' \
-b 'sysexit:exact-filename:./b' \
-- ./shell-script
Quote the breakpoint when it contains spaces or shell special characters, especially for regex patterns.
Setting Breakpoints in the TUI
When the Events pane is focused, press B to open the Breakpoint Manager.
If the Terminal pane is focused, use Ctrl+S to switch panes first.
Press N to create a new breakpoint. The editor accepts only the pattern,
such as in-filename:/my-program, without the sysenter: or sysexit: prefix.
Do not add a space after the colon unless you want that space to be part of the pattern.
New breakpoints are active and stop at Syscall Exit by default.
While editing:
- Press Alt+S to switch between
Syscall EnterandSyscall Exit. - Press Alt+A to toggle whether the breakpoint is active.
- Press Enter to save, or Ctrl+C to cancel.
In the breakpoint list, use ↑/↓ to select a breakpoint. Press Enter or E to edit it, Space to enable or disable it, or Delete/D to delete it. Press Q to return to the events pane.
Disabling or deleting a breakpoint does not resume a process that has already hit it.
Handling Breakpoint Hits
When a process hits a breakpoint, tracexec pauses that process and shows the number of hits at the bottom of the screen. Other tracees can keep running, although they may be waiting for the stopped process.
Press Z from the Events pane to open the Hit Manager.
Use ↑/↓ to select a stopped process, then:
- Press R to resume it and keep tracing it.
- Press D to detach and let it continue without tracexec tracing it.
- Press Enter to detach, leave it stopped and run the default external command.
- Press Alt+Enter to enter a command to run for this particular hit.
Press Q to close the Hit Manager. This leaves the processes stopped. You can press F1 in either manager to view its help.
Launching a Debugger
See Use tracexec as debugger launcher for a complete tutorial.
Set --default-external-command to the command you want to launch for a hit.
tracexec replaces {{PID}} with the PID of the detached and stopped process.
You can also set or edit this command by pressing E in the Hit Manager.
For example, if you use Konsole:
tracexec tui --seccomp-bpf=off \
-b 'sysexit:in-filename:/my-program' \
--default-external-command 'konsole -e gdb -p {{PID}}' \
-- bash
Run your program in the terminal pane. When it hits the breakpoint, switch to the events pane,
press Z, select the hit and press Enter.
A new terminal will open with gdb attached to the process.
You may need to run continue twice in gdb because of the stop signal used during detach.
Use a terminal emulator or a command such as tmux split-window for an interactive debugger:
the external command’s standard input, output and error are connected to /dev/null.
The command supports shell-style quoting, but is not run through a shell.
If you need shell features such as pipes or redirection, invoke a shell explicitly.
The --seccomp-bpf=off option matters if the detached process or its children need to exec
other programs. With the seccomp-bpf optimization enabled, those exec calls can fail with
Function not implemented after detach. Set this option when starting tracexec.