Debugging another user’s process

Sometimes it is necessary to debug a process belonging to another user. Usually, debuggers running with sufficient privileges can attach to another user’s processes. Under UDB this is not the case by default. With default settings, UDB may attach only to processes belonging to the same user as the debugger. It will refuse to attach to processes belonging to another user, even when the debugger is running with sufficient privileges.


Usually, a user with the CAP_PTRACE capability can attach to any other process in the system (so long as it is not already being debugged). In most configurations, this equates with the root user. These privileges are still required to attach UDB to another user’s process but are not, by themselves, adequate.

This behaviour can be overridden by activating permissive communications mode. This mode is disabled by default but can be enabled by setting an environment variable.


Permissive Communications Mode makes cross-user debugging possible but comes with security implications: it opens communications channels that any process on the system may connect to. It therefore carries a risk of local cross-user exploits.

It is therefore recommended that users avoid Permissive Communications Mode where possible. It is particularly desirable to avoid its use on shared systems. If permissive communications are specifically required (for instance, to fit within an existing debugging workflow on a dedicated system) they can be enabled via a environment variable:

UNDO_permissive_comms=true udb <args>

When starting with permissive comms mode, UDB will display a warning to remind the user of the setting currently in effect:

CAUTION: attaching with permissive comms mode

Record and replay of external device state

The Undo Engine works fine with programs that access external device state, and during replay the developer can see a copy of any external device state as far as it impacts the program being recorded. For example, when the program reads from a memory-mapped device, the values that are read are stored in our event log.

In general, a detailed view of the external device state is not necessary in order to be able to debug problems in the software that controls that external device. What matters is the inputs and outputs to the device, for which the Undo Engine gives full visibility.

It’s important to note that the Undo Engine don’t just make a recording of the system events (in the manner of a tool such as strace), but it records the program in a manner that allows the reconstruction of all of the state and events produced by the program at any time in its history, whether or not they interact with the underlying system.

Synchronized debugging

The Undo Engine does not allow synchronized debugging between multiple processes at present.

Kernel-space memory

The Undo Engine only records user-space memory.

Streamed recording

The Undo Engine records to an in-memory event log. Streaming the event log to an external location is not currently implemented, but we hope to address this in the future.

Performance analysis

The Undo Engine can tell you about what system calls were executed, and when they were executed. And of course you can set breakpoints on code that handles particular cases. However the Undo Engine only supports user-mode execution, and recording the kernel is not supported.

Finding memory leaks

The Undo Engine cannot perform memory leak detection automatically, but it can assist in the process of searching for memory leaks.

For example, you could set a watchpoint in the struct malloc_chunk describing an allocated block, and run backwards to find the point where that data structure was modified, and so discover which code allocated the block.

The Undo Engine also supports debugging code compiled with Clang’s sanitizers such as AddressSanitizer or LeakSanitizer.