[lldb-dev] How does attach work on non-Windows?

Pavel Labath via lldb-dev lldb-dev at lists.llvm.org
Thu Aug 27 01:41:34 PDT 2015

The main issue I see with all these APIs is that they are
non-blocking. That is, the test executable cannot simply say "wait
until a debugger attaches", but it will have to do something like:
while (! attached) {
  attached = figure_out_if_i_am_attached_using_architecture_specific_methods();

This does not sound to me like it will be significantly more stable
then the currently used method:
while (! attached) sleep(X);
where the debugger flips the variable after it attaches.

However, I would definitely welcome providing a default implementation
of wait_for_debugger_attach() (regardless of how it is implemented),
which all tests can use, instead of each one rolling out its own.

Another possible implementation would be to use some standard IPC
mechanism (pipes, signals, sockets, ...) for waking up the inferior
once the debugger is ready. The test inferior could e.g., wait on a
pipe and the debugger will write a single byte there once it attaches.
Since we control both the test runner and the test inferior, this is
enough and you don't need any fancy APIs. The tricky part here would
be to make sure this works during remote debugging.

That said, I don't think the current issues with the attach tests are
caused by this problem. The current protocol, however awkard it may
be, should still work IMO, but we are still seeing flakyness in all
tests that do attaches. I think we have some other issues here and I
am suspecting races in other parts of the system. I was planning to
take a look at these soon...

> LLDB picks this up, and the result is that LLDB stops and waits for the user
> to continue the inferior just as it would with any other breakpoint, and if
> you were to get a backtrace you might see something like this:
> looking at: Stack traces for SBProcess: pid = 12588, state = stopped,
> threads = 2, executable = test_with_dwarf_and_attach_to_process_with_id_api
> Stack trace for thread id=0x3428 name=None queue=None stop reason=none
>   frame #0: 0xffffffffffffffff ntdll.dll`DbgBreakPoint + 1

This sounds like a pretty strange way to stop the inferior (I was
quite surprised that ^C also injects a thread into a program), however
it is fundamentally equivalent to what the other platforms do. When we
attach on Linux, the inferior also comes out stopped. The difference
is that we get a SIGSTOP as a stop reason, while on windows you get a
breakpoint in a different thread. It sounds to me like the tests
should not rely on a specific thread being selected after the attach.
Most tests don't do backtraces right after attach since you're likely
to get very unpredictable results on any platform. Those that do
should be fixed to set a breakpoint on the place that interests them,
resume and do a backtrace once they hit that breakpoint. I vaguelly
recall some tests that actually do try to backtrace on attach on
purpose (for example, to see if you can backtrace out of a syscall).
If they exist, we should fix them to first select the right thread for
the backtracing, so they don't try to use the DbgBreakPoint thread.

More information about the lldb-dev mailing list