[v2,4/6] Use LWP IDs with ptrace register requests on FreeBSD.

Message ID 1452721551-657-5-git-send-email-jhb@FreeBSD.org
State New, archived
Headers

Commit Message

John Baldwin Jan. 13, 2016, 9:45 p.m. UTC
  This allows gdb to fetch per-thread registers for multi-threaded FreeBSD
processes.  NetBSD and OpenBSD also accept LWP IDs for ptrace requests
to fetch per-thread state.

gdb/ChangeLog:

	* amd64bsd-nat.c (get_ptrace_pid): New function.
	(amd64bsd_fetch_inferior_registers): Use new function.
	(amd64bsd_store_inferior_registers): Use new function.
	(amd64bsd_dr_get): Use new function.
	(amd64bsd_dr_set): Use new function.
	* i386bsd-nat.c (get_ptrace_pid): New function.
	(i386bsd_fetch_inferior_registers): Use new function.
	(i386bsd_store_inferior_registers): Use new function.
	(i386bsd_dr_get): Use new function.
	(i386bsd_dr_set): Use new function.
	* ppcfbsd-nat.c (get_ptrace_pid): New function.
	(ppcfbsd_fetch_inferior_registers): Use new function.
	(ppcfbsd_store_inferior_registers): Use new function.
---
 gdb/ChangeLog      | 15 +++++++++++++++
 gdb/amd64bsd-nat.c | 35 +++++++++++++++++++++++------------
 gdb/i386bsd-nat.c  | 41 ++++++++++++++++++++++++++---------------
 gdb/ppcfbsd-nat.c  | 23 +++++++++++++++++------
 4 files changed, 81 insertions(+), 33 deletions(-)
  

Comments

Pedro Alves Jan. 14, 2016, 3:07 p.m. UTC | #1
[Dropping binutils.]

On 01/13/2016 09:45 PM, John Baldwin wrote:
> This allows gdb to fetch per-thread registers for multi-threaded FreeBSD
> processes.  NetBSD and OpenBSD also accept LWP IDs for ptrace requests
> to fetch per-thread state.

I'd prefer to make inf-ptrace.c:get_ptrace_pid extern and use
it, instead of duplicating it multiple times.

Thanks,
Pedro Alves
  
John Baldwin Jan. 15, 2016, 8:18 p.m. UTC | #2
On Thursday, January 14, 2016 03:07:28 PM Pedro Alves wrote:
> [Dropping binutils.]
> 
> On 01/13/2016 09:45 PM, John Baldwin wrote:
> > This allows gdb to fetch per-thread registers for multi-threaded FreeBSD
> > processes.  NetBSD and OpenBSD also accept LWP IDs for ptrace requests
> > to fetch per-thread state.
> 
> I'd prefer to make inf-ptrace.c:get_ptrace_pid extern and use
> it, instead of duplicating it multiple times.

This sounds good to me.  Do you want me to use it in other places as well?
sparc-nat.c at least duplicates the same logic inline.  amd64linux-nat.c
does as well.  If so, would you rather that be a seperate patch (expose
get_ptrace_pid() and use it in existing targets) from this patch?
  
Pedro Alves Jan. 15, 2016, 9:41 p.m. UTC | #3
On 01/15/2016 08:18 PM, John Baldwin wrote:
> On Thursday, January 14, 2016 03:07:28 PM Pedro Alves wrote:
>> [Dropping binutils.]
>>
>> On 01/13/2016 09:45 PM, John Baldwin wrote:
>>> This allows gdb to fetch per-thread registers for multi-threaded FreeBSD
>>> processes.  NetBSD and OpenBSD also accept LWP IDs for ptrace requests
>>> to fetch per-thread state.
>>
>> I'd prefer to make inf-ptrace.c:get_ptrace_pid extern and use
>> it, instead of duplicating it multiple times.
> 
> This sounds good to me.  Do you want me to use it in other places as well?
> sparc-nat.c at least duplicates the same logic inline.  amd64linux-nat.c
> does as well.  If so, would you rather that be a seperate patch (expose
> get_ptrace_pid() and use it in existing targets) from this patch?

I won't impose that as requirement, but that'd be nice.

Thanks,
Pedro Alves
  
John Baldwin Jan. 15, 2016, 11:22 p.m. UTC | #4
On Friday, January 15, 2016 09:41:19 PM Pedro Alves wrote:
> On 01/15/2016 08:18 PM, John Baldwin wrote:
> > On Thursday, January 14, 2016 03:07:28 PM Pedro Alves wrote:
> >> [Dropping binutils.]
> >>
> >> On 01/13/2016 09:45 PM, John Baldwin wrote:
> >>> This allows gdb to fetch per-thread registers for multi-threaded FreeBSD
> >>> processes.  NetBSD and OpenBSD also accept LWP IDs for ptrace requests
> >>> to fetch per-thread state.
> >>
> >> I'd prefer to make inf-ptrace.c:get_ptrace_pid extern and use
> >> it, instead of duplicating it multiple times.
> > 
> > This sounds good to me.  Do you want me to use it in other places as well?
> > sparc-nat.c at least duplicates the same logic inline.  amd64linux-nat.c
> > does as well.  If so, would you rather that be a seperate patch (expose
> > get_ptrace_pid() and use it in existing targets) from this patch?
> 
> I won't impose that as requirement, but that'd be nice.

Ok.  I made a pass and fixed the ones that I thought were relevant (i.e.
generating a pid to pass to ptrace()).   However, the vast majority of the
files changed were various foo-linux-nat.c files which I am not setup to
test.  Is there a way to push a branch and have the build bots build it to
do a test build?  (Even then I think those would not cover 'nat' files for
s390, hppa, etc.)  I'm still happy to include this, just want to ensure I
don't break the build.  I'm also not sure if changing these files would
break gdbserver (if gdbserver doesn't include inf-ptrace.o).
  
Pedro Alves Jan. 16, 2016, 2:39 p.m. UTC | #5
On 01/15/2016 11:22 PM, John Baldwin wrote:

> Ok.  I made a pass and fixed the ones that I thought were relevant (i.e.
> generating a pid to pass to ptrace()).   However, the vast majority of the
> files changed were various foo-linux-nat.c files which I am not setup to
> test.  

Hmm, actually, sorry about that, but I remembered that the ptid_get_lwp()==0
paths in Linux code are dead code (90ad5e1d4f).  I see now that d89fa914ad6f
cleaned most of the linux code, but left out the cases that were open coded.

So I think it's best to just leave those be.  Someone can always clean
those up to use ptid_get_lwp directly afterwards.

I now think that to move forward with your patch, it's simpler/better to
export get_ptrace_pid, and just use it in the cases you cared about,
and leave other targets as is.

If you're changing the FreeBSD to always store an lwp, do you still
need get_ptrace_pid, or would something like this instead work?

-      if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+      if (ptrace (PT_GETREGS, get_ptrace_lwp (inferior_ptid),

etc.  Or would you still need it because the foo-nat.c files you're
touching are used by other BSDs as well?

> Is there a way to push a branch and have the build bots build it to
> do a test build?  

No, sorry.

> (Even then I think those would not cover 'nat' files for
> s390, hppa, etc.)  I'm still happy to include this, just want to ensure I
> don't break the build.

>  I'm also not sure if changing these files would
> break gdbserver (if gdbserver doesn't include inf-ptrace.o).

gdbserver does not include inf-ptrace.o, but it doesn't use the
gdb/*-nat.c files either.  It has its own backends and shares
the gdb/nat/, gdb/common/ and gdb/arch/ files with gdb.

We'd actually like to merge the existing gdbserver/gdb backends
though:

  https://sourceware.org/gdb/wiki/Common

Thanks,
Pedro Alves
  
John Baldwin Jan. 16, 2016, 6:35 p.m. UTC | #6
On Saturday, January 16, 2016 02:39:34 PM Pedro Alves wrote:
> On 01/15/2016 11:22 PM, John Baldwin wrote:
> 
> > Ok.  I made a pass and fixed the ones that I thought were relevant (i.e.
> > generating a pid to pass to ptrace()).   However, the vast majority of the
> > files changed were various foo-linux-nat.c files which I am not setup to
> > test.  
> 
> Hmm, actually, sorry about that, but I remembered that the ptid_get_lwp()==0
> paths in Linux code are dead code (90ad5e1d4f).  I see now that d89fa914ad6f
> cleaned most of the linux code, but left out the cases that were open coded.
> 
> So I think it's best to just leave those be.  Someone can always clean
> those up to use ptid_get_lwp directly afterwards.
> 
> I now think that to move forward with your patch, it's simpler/better to
> export get_ptrace_pid, and just use it in the cases you cared about,
> and leave other targets as is.

Ok.

> If you're changing the FreeBSD to always store an lwp, do you still
> need get_ptrace_pid, or would something like this instead work?
> 
> -      if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
> +      if (ptrace (PT_GETREGS, get_ptrace_lwp (inferior_ptid),
> 
> etc.  Or would you still need it because the foo-nat.c files you're
> touching are used by other BSDs as well?

Most of them are pan-BSD so they would need the helper, but ppcfbsd-nat.c
is FreeBSD-only, so it can use ptid_get_lwp() directly.
  

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 93760ba..0accac9 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,18 @@ 
+2016-01-10  John Baldwin  <jhb@FreeBSD.org>
+	* amd64bsd-nat.c (get_ptrace_pid): New function.
+	(amd64bsd_fetch_inferior_registers): Use new function.
+	(amd64bsd_store_inferior_registers): Use new function.
+	(amd64bsd_dr_get): Use new function.
+	(amd64bsd_dr_set): Use new function.
+	* i386bsd-nat.c (get_ptrace_pid): New function.
+	(i386bsd_fetch_inferior_registers): Use new function.
+	(i386bsd_store_inferior_registers): Use new function.
+	(i386bsd_dr_get): Use new function.
+	(i386bsd_dr_set): Use new function.
+	* ppcfbsd-nat.c (get_ptrace_pid): New function.
+	(ppcfbsd_fetch_inferior_registers): Use new function.
+	(ppcfbsd_store_inferior_registers): Use new function.
+
 2016-01-09  John Baldwin  <jhb@FreeBSD.org>
 
 	* fbsd_tdep.c (fbsd_core_pid_to_str): New function.
diff --git a/gdb/amd64bsd-nat.c b/gdb/amd64bsd-nat.c
index aa79c13..7e4adc8 100644
--- a/gdb/amd64bsd-nat.c
+++ b/gdb/amd64bsd-nat.c
@@ -39,6 +39,17 @@ 
 size_t amd64bsd_xsave_len;
 #endif
 
+static pid_t
+get_ptrace_pid (ptid_t ptid)
+{
+  pid_t pid;
+
+  pid = ptid_get_lwp (ptid);
+  if (pid == 0)
+    pid = ptid_get_pid (ptid);
+  return pid;
+}
+  
 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
    for all registers (including the floating-point registers).  */
 
@@ -52,7 +63,7 @@  amd64bsd_fetch_inferior_registers (struct target_ops *ops,
     {
       struct reg regs;
 
-      if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+      if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
 	perror_with_name (_("Couldn't get registers"));
 
@@ -70,7 +81,7 @@  amd64bsd_fetch_inferior_registers (struct target_ops *ops,
       if (amd64bsd_xsave_len != 0)
 	{
 	  xstateregs = alloca (amd64bsd_xsave_len);
-	  if (ptrace (PT_GETXSTATE, ptid_get_pid (inferior_ptid),
+	  if (ptrace (PT_GETXSTATE, get_ptrace_pid (inferior_ptid),
 		      (PTRACE_TYPE_ARG3) xstateregs, 0) == -1)
 	    perror_with_name (_("Couldn't get extended state status"));
 
@@ -79,7 +90,7 @@  amd64bsd_fetch_inferior_registers (struct target_ops *ops,
 	}
 #endif
 
-      if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
+      if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
 	perror_with_name (_("Couldn't get floating point status"));
 
@@ -100,13 +111,13 @@  amd64bsd_store_inferior_registers (struct target_ops *ops,
     {
       struct reg regs;
 
-      if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+      if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid),
                   (PTRACE_TYPE_ARG3) &regs, 0) == -1)
         perror_with_name (_("Couldn't get registers"));
 
       amd64_collect_native_gregset (regcache, &regs, regnum);
 
-      if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
+      if (ptrace (PT_SETREGS, get_ptrace_pid (inferior_ptid),
 	          (PTRACE_TYPE_ARG3) &regs, 0) == -1)
         perror_with_name (_("Couldn't write registers"));
 
@@ -123,26 +134,26 @@  amd64bsd_store_inferior_registers (struct target_ops *ops,
       if (amd64bsd_xsave_len != 0)
 	{
 	  xstateregs = alloca (amd64bsd_xsave_len);
-	  if (ptrace (PT_GETXSTATE, ptid_get_pid (inferior_ptid),
+	  if (ptrace (PT_GETXSTATE, get_ptrace_pid (inferior_ptid),
 		      (PTRACE_TYPE_ARG3) xstateregs, 0) == -1)
 	    perror_with_name (_("Couldn't get extended state status"));
 
 	  amd64_collect_xsave (regcache, regnum, xstateregs, 0);
 
-	  if (ptrace (PT_SETXSTATE, ptid_get_pid (inferior_ptid),
+	  if (ptrace (PT_SETXSTATE, get_ptrace_pid (inferior_ptid),
 		      (PTRACE_TYPE_ARG3) xstateregs, amd64bsd_xsave_len) == -1)
 	    perror_with_name (_("Couldn't write extended state status"));
 	  return;
 	}
 #endif
 
-      if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
+      if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
 	perror_with_name (_("Couldn't get floating point status"));
 
       amd64_collect_fxsave (regcache, regnum, &fpregs);
 
-      if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
+      if (ptrace (PT_SETFPREGS, get_ptrace_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
 	perror_with_name (_("Couldn't write floating point status"));
     }
@@ -172,7 +183,7 @@  amd64bsd_dr_get (ptid_t ptid, int regnum)
 {
   struct dbreg dbregs;
 
-  if (ptrace (PT_GETDBREGS, ptid_get_pid (inferior_ptid),
+  if (ptrace (PT_GETDBREGS, get_ptrace_pid (inferior_ptid),
 	      (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
     perror_with_name (_("Couldn't read debug registers"));
 
@@ -184,7 +195,7 @@  amd64bsd_dr_set (int regnum, unsigned long value)
 {
   struct dbreg dbregs;
 
-  if (ptrace (PT_GETDBREGS, ptid_get_pid (inferior_ptid),
+  if (ptrace (PT_GETDBREGS, get_ptrace_pid (inferior_ptid),
               (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
     perror_with_name (_("Couldn't get debug registers"));
 
@@ -195,7 +206,7 @@  amd64bsd_dr_set (int regnum, unsigned long value)
 
   DBREG_DRX ((&dbregs), regnum) = value;
 
-  if (ptrace (PT_SETDBREGS, ptid_get_pid (inferior_ptid),
+  if (ptrace (PT_SETDBREGS, get_ptrace_pid (inferior_ptid),
               (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
     perror_with_name (_("Couldn't write debug registers"));
 }
diff --git a/gdb/i386bsd-nat.c b/gdb/i386bsd-nat.c
index 71f962c..df112c3 100644
--- a/gdb/i386bsd-nat.c
+++ b/gdb/i386bsd-nat.c
@@ -87,6 +87,17 @@  size_t i386bsd_xsave_len;
 #endif
 
 
+static pid_t
+get_ptrace_pid (ptid_t ptid)
+{
+  pid_t pid;
+
+  pid = ptid_get_lwp (ptid);
+  if (pid == 0)
+    pid = ptid_get_pid (ptid);
+  return pid;
+}
+  
 /* Supply the general-purpose registers in GREGS, to REGCACHE.  */
 
 static void
@@ -138,7 +149,7 @@  i386bsd_fetch_inferior_registers (struct target_ops *ops,
     {
       struct reg regs;
 
-      if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+      if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &regs, 0) == -1)
 	perror_with_name (_("Couldn't get registers"));
 
@@ -160,7 +171,7 @@  i386bsd_fetch_inferior_registers (struct target_ops *ops,
 	  char *xstateregs;
 
 	  xstateregs = alloca (i386bsd_xsave_len);
-	  if (ptrace (PT_GETXSTATE, ptid_get_pid (inferior_ptid),
+	  if (ptrace (PT_GETXSTATE, get_ptrace_pid (inferior_ptid),
 		      (PTRACE_TYPE_ARG3) xstateregs, 0) == -1)
 	    perror_with_name (_("Couldn't get extended state status"));
 
@@ -171,7 +182,7 @@  i386bsd_fetch_inferior_registers (struct target_ops *ops,
       
 #ifdef HAVE_PT_GETXMMREGS
       if (have_ptrace_xmmregs != 0
-	  && ptrace(PT_GETXMMREGS, ptid_get_pid (inferior_ptid),
+	  && ptrace(PT_GETXMMREGS, get_ptrace_pid (inferior_ptid),
 		    (PTRACE_TYPE_ARG3) xmmregs, 0) == 0)
 	{
 	  have_ptrace_xmmregs = 1;
@@ -181,7 +192,7 @@  i386bsd_fetch_inferior_registers (struct target_ops *ops,
 	{
 	  have_ptrace_xmmregs = 0;
 #endif
-          if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
+          if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid),
 		      (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
 	    perror_with_name (_("Couldn't get floating point status"));
 
@@ -203,13 +214,13 @@  i386bsd_store_inferior_registers (struct target_ops *ops,
     {
       struct reg regs;
 
-      if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+      if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid),
                   (PTRACE_TYPE_ARG3) &regs, 0) == -1)
         perror_with_name (_("Couldn't get registers"));
 
       i386bsd_collect_gregset (regcache, &regs, regnum);
 
-      if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
+      if (ptrace (PT_SETREGS, get_ptrace_pid (inferior_ptid),
 	          (PTRACE_TYPE_ARG3) &regs, 0) == -1)
         perror_with_name (_("Couldn't write registers"));
 
@@ -230,13 +241,13 @@  i386bsd_store_inferior_registers (struct target_ops *ops,
 	  char *xstateregs;
 
 	  xstateregs = alloca (i386bsd_xsave_len);
-	  if (ptrace (PT_GETXSTATE, ptid_get_pid (inferior_ptid),
+	  if (ptrace (PT_GETXSTATE, get_ptrace_pid (inferior_ptid),
 		      (PTRACE_TYPE_ARG3) xstateregs, 0) == -1)
 	    perror_with_name (_("Couldn't get extended state status"));
 
 	  i387_collect_xsave (regcache, -1, xstateregs, 0);
 
-	  if (ptrace (PT_SETXSTATE, ptid_get_pid (inferior_ptid),
+	  if (ptrace (PT_SETXSTATE, get_ptrace_pid (inferior_ptid),
 		      (PTRACE_TYPE_ARG3) xstateregs, i386bsd_xsave_len) == -1)
 	    perror_with_name (_("Couldn't write extended state status"));
 	  return;
@@ -245,14 +256,14 @@  i386bsd_store_inferior_registers (struct target_ops *ops,
 
 #ifdef HAVE_PT_GETXMMREGS
       if (have_ptrace_xmmregs != 0
-	  && ptrace(PT_GETXMMREGS, ptid_get_pid (inferior_ptid),
+	  && ptrace(PT_GETXMMREGS, get_ptrace_pid (inferior_ptid),
 		    (PTRACE_TYPE_ARG3) xmmregs, 0) == 0)
 	{
 	  have_ptrace_xmmregs = 1;
 
 	  i387_collect_fxsave (regcache, regnum, xmmregs);
 
-	  if (ptrace (PT_SETXMMREGS, ptid_get_pid (inferior_ptid),
+	  if (ptrace (PT_SETXMMREGS, get_ptrace_pid (inferior_ptid),
 		      (PTRACE_TYPE_ARG3) xmmregs, 0) == -1)
             perror_with_name (_("Couldn't write XMM registers"));
 	}
@@ -260,13 +271,13 @@  i386bsd_store_inferior_registers (struct target_ops *ops,
 	{
 	  have_ptrace_xmmregs = 0;
 #endif
-          if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
+          if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid),
 		      (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
 	    perror_with_name (_("Couldn't get floating point status"));
 
           i387_collect_fsave (regcache, regnum, &fpregs);
 
-          if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
+          if (ptrace (PT_SETFPREGS, get_ptrace_pid (inferior_ptid),
 		      (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
 	    perror_with_name (_("Couldn't write floating point status"));
 #ifdef HAVE_PT_GETXMMREGS
@@ -305,7 +316,7 @@  i386bsd_dr_get (ptid_t ptid, int regnum)
 {
   struct dbreg dbregs;
 
-  if (ptrace (PT_GETDBREGS, ptid_get_pid (inferior_ptid),
+  if (ptrace (PT_GETDBREGS, get_ptrace_pid (inferior_ptid),
 	      (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
     perror_with_name (_("Couldn't read debug registers"));
 
@@ -317,7 +328,7 @@  i386bsd_dr_set (int regnum, unsigned int value)
 {
   struct dbreg dbregs;
 
-  if (ptrace (PT_GETDBREGS, ptid_get_pid (inferior_ptid),
+  if (ptrace (PT_GETDBREGS, get_ptrace_pid (inferior_ptid),
               (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
     perror_with_name (_("Couldn't get debug registers"));
 
@@ -328,7 +339,7 @@  i386bsd_dr_set (int regnum, unsigned int value)
 
   DBREG_DRX ((&dbregs), regnum) = value;
 
-  if (ptrace (PT_SETDBREGS, ptid_get_pid (inferior_ptid),
+  if (ptrace (PT_SETDBREGS, get_ptrace_pid (inferior_ptid),
               (PTRACE_TYPE_ARG3) &dbregs, 0) == -1)
     perror_with_name (_("Couldn't write debug registers"));
 }
diff --git a/gdb/ppcfbsd-nat.c b/gdb/ppcfbsd-nat.c
index b41ed70..e4240c8 100644
--- a/gdb/ppcfbsd-nat.c
+++ b/gdb/ppcfbsd-nat.c
@@ -37,6 +37,17 @@ 
 #include "inf-ptrace.h"
 #include "bsd-kvm.h"
 
+static pid_t
+get_ptrace_pid (ptid_t ptid)
+{
+  pid_t pid;
+
+  pid = ptid_get_lwp (ptid);
+  if (pid == 0)
+    pid = ptid_get_pid (ptid);
+  return pid;
+}
+  
 /* Fill GDB's register array with the general-purpose register values
    in *GREGSETP.  */
 
@@ -121,7 +132,7 @@  ppcfbsd_fetch_inferior_registers (struct target_ops *ops,
 {
   gdb_gregset_t regs;
 
-  if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+  if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid),
 	      (PTRACE_TYPE_ARG3) &regs, 0) == -1)
     perror_with_name (_("Couldn't get registers"));
 
@@ -132,7 +143,7 @@  ppcfbsd_fetch_inferior_registers (struct target_ops *ops,
       const struct regset *fpregset = ppc_fbsd_fpregset ();
       gdb_fpregset_t fpregs;
 
-      if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
+      if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
 	perror_with_name (_("Couldn't get FP registers"));
 
@@ -149,13 +160,13 @@  ppcfbsd_store_inferior_registers (struct target_ops *ops,
 {
   gdb_gregset_t regs;
 
-  if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
+  if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid),
 	      (PTRACE_TYPE_ARG3) &regs, 0) == -1)
     perror_with_name (_("Couldn't get registers"));
 
   fill_gregset (regcache, &regs, regno);
 
-  if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
+  if (ptrace (PT_SETREGS, get_ptrace_pid (inferior_ptid),
 	      (PTRACE_TYPE_ARG3) &regs, 0) == -1)
     perror_with_name (_("Couldn't write registers"));
 
@@ -163,13 +174,13 @@  ppcfbsd_store_inferior_registers (struct target_ops *ops,
     {
       gdb_fpregset_t fpregs;
 
-      if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
+      if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
 	perror_with_name (_("Couldn't get FP registers"));
 
       fill_fpregset (regcache, &fpregs, regno);
 
-      if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
+      if (ptrace (PT_SETFPREGS, get_ptrace_pid (inferior_ptid),
 		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
 	perror_with_name (_("Couldn't set FP registers"));
     }