Supporting gdb was significantly more complicated. Since use of ptrace
is essential for the virtualization of system calls, a process can
only be under ptrace by one other process, and gdb also requires ptrace,
there is a problem attaching gdb to a UML process.

This is fixed by having gdb started and ptraced by the tracing thread
and, by intercepting its system calls, faking it into believing that
it is attached to UML. gdb's calls to ptrace and a few other system
calls are intercepted, emulated by the tracing thread, and the return
values imposed on gdb. This works well enough that the user can't
tell that gdb isn't really attached to UML.

This support has also been extended to allow external debuggers to
be attached. This enables UML to be debugged by an already-running
gdb, such as one running under a front-end like emacs or ddd. It also
allows debuggers other than gdb, like strace, to be attached to UML.