This is the mail archive of the gdb@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

gdbserver ptrace not doing waitpid after attaching to threads?


Hi.

There's something about gdbserver's use of ptrace that I don't understand
and I'm hoping someone can help.

AIUI, after attaching to a thread (or process) one must wait until
the thread has stopped before one can, for example, read regs.
[Well, one can cheat and assume enough time passes before trying to read
regs, but that's cheating. :-)]
If one tries to read regs too soon ptrace will return with ESRCH.

This is the behaviour I'm seeing in a version of gdbserver I'm hacking on -
my register reads are intermittently failing with ESRCH.  If I add code to
wait for SIGSTOP after attaching to all the threads then my register reads
start working.

However, gdb+gdbserver works just fine (obviously), and in fact there is
code in gdbserver to explicitly skip/ignore the initial SIGSTOP in
linux-low.c:linux_attach_lwp:

  /* The next time we wait for this LWP we'll see a SIGSTOP as PTRACE_ATTACH
     brings it to a halt.  We should ignore that SIGSTOP and resume the process
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^
     (unless this is the first process, in which case the flag will be cleared
     in linux_attach).

     On the other hand, if we are currently trying to stop all threads, we
     should treat the new thread as if we had sent it a SIGSTOP.  This works
     because we are guaranteed that add_process added us to the end of the
     list, and so the new thread has not yet reached wait_for_sigstop (but
     will).  */
  if (! stopping_threads)
    new_process->stop_expected = 1;

and there is code linux_attach to undo this because for main thread
we *do* want to wait for the initial SIGSTOP after attaching to the process:

  /* Don't ignore the initial SIGSTOP if we just attached to this process.
     It will be collected by wait shortly.  */
  process = (struct process_info *) find_inferior_id (&all_processes, pid);
  process->stop_expected = 0;

Anyone know what's going on here?
Why the different treatment for the main thread vs the others?
Why isn't gdbserver waiting for a SIGSTOP after attaching to threads?

I've run gdbserver under strace and see that gdbserver is essentially doing
ptrace (ATTACH), ptrace (SETOPTIONS), ptrace (GETREGS) on threads
with no intervening waitpid.

I wonder if gdb is working just because of luck: maybe enough packets go back
and forth before gdb tries to read regs that all threads have stopped
by the time gdb needs them to have stopped.
In my hacked gdbserver I'm doing a register read almost immediately
after attaching.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]