[PATCH] Linux/ptrace: don't convert ptids when asking inf-ptrace layer to resume LWP
Mark Kettenis
mark.kettenis@xs4all.nl
Tue Mar 3 16:04:00 GMT 2015
> Date: Tue, 03 Mar 2015 15:12:48 +0000
> From: Pedro Alves <palves@redhat.com>
>
> On 03/03/2015 02:39 PM, Mark Kettenis wrote:
> >> From: Pedro Alves <palves@redhat.com>
> >> Date: Tue, 3 Mar 2015 13:33:44 +0000
> >>
> >> Tested on x86-64 Fedora 20, -m32.
> >>
> >> gdb/ChangeLog:
> >> 2015-03-03 Pedro Alves <palves@redhat.com>
> >>
> >> * i386-linux-nat.c (i386_linux_resume): Get the ptrace PID out of
> >> the lwp field of ptid. Pass the full ptid to get_thread_regcache.
> >> * inf-ptrace.c (get_ptrace_pid): New function.
> >> (inf_ptrace_resume): Use it.
> >> * linux-nat.c (linux_resume_one_lwp): Pass the LWP's ptid ummodified
> >> to the lower layer.
> >> ---
> >> gdb/ChangeLog | 9 +++++++++
> >> gdb/i386-linux-nat.c | 5 ++---
> >> gdb/inf-ptrace.c | 25 ++++++++++++++++++++++---
> >> gdb/linux-nat.c | 6 +-----
> >> 4 files changed, 34 insertions(+), 11 deletions(-)
> >
> > I have some fear this is going to break non-Linux targets.
> >
> >> --- a/gdb/inf-ptrace.c
> >> +++ b/gdb/inf-ptrace.c
> >> - if (pid == -1)
> >> + if (ptid_equal (minus_one_ptid, ptid))
> >> /* Resume all threads. Traditionally ptrace() only supports
> >> single-threaded processes, so simply resume the inferior. */
> >> - pid = ptid_get_pid (inferior_ptid);
> >> + pid = get_ptrace_pid (inferior_ptid);
> >
> > This defenitely should remain ptid_get_pid(); you want to resume the
> > entire process and not an individual thread.
>
> My thinking is that it doesn't matter in practice.
>
> Or is it that if there are multiple kernel threads in the
> process, ptrace(PTRACE_CONT, PID) on bsd actually resumes
> them all? Then other things must be broken anyway.
I can only speak for OpenBSD here, but yes, on OpenBSD, if you pass
"PID" here, all threads within a process are resumed. If you want to
resume an individual thread, you need to pass its thread ID. Thread
IDs are also integers, but start at THREAD_PID_OFFSET, which is
currently defined as 1000000.
Are things broken? Perhaps. GDB used to properly support an
all-stop/all-go model, and things still seem to work mostly ok.
Perhaps this diff will actually make things better if there are places
where GDB wants to resume or step a single thread that isn't the
thread that stopped the process in the first place.
I've always considered it a serious flaw that Linux doesn't have a way
to resume the entire process and that we need almost 5000 lines of
code to deal with the consequences.
> I was assuming that on BSD targets that use this method,
> there would only be one thread in the core thread list, and
> it would either have LWPID==0, or have PID==LWPID, thus it didn't
> matter if get_ptrace_pid returned the PID or the LWPID.
That assumption is incorrect. I see that this assumption has made its
way into infrun.c:
inferior_ptid = ptid_build (child_pid, child_pid, 0);
That's wrong. The OS-specific code should fill in the LWPID part with
the appropriate value by using thread_change_ptid(). AFAICT, the
linux-nat.c code does that properly.
> If there anything that actually creates other threads with
> a different LWPID on these targets?
The initial thread ID of an OpenBSD process will be PID + THREAD_PID_OFFSET.
More information about the Gdb-patches
mailing list