[v2] Remove lwp -> pid conversion in linux_nat_xfer_partial

Message ID 20170322030215.27737-1-simon.marchi@polymtl.ca
State New, archived
Headers

Commit Message

Simon Marchi March 22, 2017, 3:02 a.m. UTC
  New in v2:

  - Use lwp in linux_proc_xfer_partial and linux_proc_xfer_spu.
  - Updated commit message (stole some of Pedro's text)

The linux_nat_xfer_partial does a conversion of inferior_ptid: if it's
an LWP (ptid::lwp != 0), it builds a new ptid with the lwp as
the pid and assigns that temporarily to inferior_ptid.  For example, if
inferior_ptid is:

  { .pid = 1234, .lwp = 1235 }

it will assign this to inferior_ptid for the duration of the call:

  { .pid = 1235, .lwp = 0 }

Instead of doing this, this patch teaches the inf-ptrace implementation
of xfer_partial to deal with ptids representing lwps by using
get_ptrace_pid.

Also, in linux_proc_xfer_spu and linux_proc_xfer_partial, we use ptid_get_lwp
instead of ptid_get_pid.  While not strictly necessary, since the content of
/proc/<pid> and /proc/<lwp> should be the same, it's a bit safer, because:

- some files under /proc/<pid>/ may not work if the <pid> thread is
  running, just like ptrace requires a stopped thread.  The current
  thread's lwp id is more likely to be in the necessary state (stopped).

- if the leader exits, and goes zombie, then several files under
  "/proc/<pid>" won't work, though using "/proc/<pid>/task/<tid>" would.
  The latter path form is also generally better for being robust in
  the case TID exits and is reused in another process, much like
  tkill vs tgkill.

The testsuite found no regression on native amd64 linux.

gdb/ChangeLog:

    * inf-ptrace.c (inf_ptrace_xfer_partial): Get pid from ptid
    using get_ptrace_pid.
    * linux-nat.c (linux_nat_xfer_partial): Don't set/restore
    inferior_ptid.
    (linux_proc_xfer_partial, linux_proc_xfer_spu): Use lwp of
    inferior_ptid instead of pid.
---
 gdb/inf-ptrace.c |  2 +-
 gdb/linux-nat.c  | 13 +++----------
 2 files changed, 4 insertions(+), 11 deletions(-)
  

Comments

Pedro Alves March 22, 2017, 11:28 a.m. UTC | #1
On 03/22/2017 03:02 AM, Simon Marchi wrote:
> New in v2:
> 
>   - Use lwp in linux_proc_xfer_partial and linux_proc_xfer_spu.
>   - Updated commit message (stole some of Pedro's text)

Thanks!

> - if the leader exits, and goes zombie, then several files under
>   "/proc/<pid>" won't work, though using "/proc/<pid>/task/<tid>" would.
>   The latter path form is also generally better for being robust in
>   the case TID exits and is reused in another process, much like
>   tkill vs tgkill.

The part about TID-reuse robustness actually doesn't make sense here
yet, though, since this patch is not switching to "/proc/<pid>/task/<tid>".

So reduce that to:

- if the leader (<pid>) had exited and is thus now zombie, then several
  files under "/proc/<pid>" won't work, while they will if you use
  "/proc/<lwp>".

Otherwise LGTM.

Thanks,
Pedro Alves
  
Simon Marchi March 22, 2017, 2:35 p.m. UTC | #2
On 2017-03-22 07:28, Pedro Alves wrote:
>> - if the leader exits, and goes zombie, then several files under
>>   "/proc/<pid>" won't work, though using "/proc/<pid>/task/<tid>" 
>> would.
>>   The latter path form is also generally better for being robust in
>>   the case TID exits and is reused in another process, much like
>>   tkill vs tgkill.
> 
> The part about TID-reuse robustness actually doesn't make sense here
> yet, though, since this patch is not switching to 
> "/proc/<pid>/task/<tid>".
> 
> So reduce that to:
> 
> - if the leader (<pid>) had exited and is thus now zombie, then several
>   files under "/proc/<pid>" won't work, while they will if you use
>   "/proc/<lwp>".
> 
> Otherwise LGTM.

Pushed with that fixed, thanks!
  

Patch

diff --git a/gdb/inf-ptrace.c b/gdb/inf-ptrace.c
index 61d24269a8..f912d28088 100644
--- a/gdb/inf-ptrace.c
+++ b/gdb/inf-ptrace.c
@@ -520,7 +520,7 @@  inf_ptrace_xfer_partial (struct target_ops *ops, enum target_object object,
 			 const gdb_byte *writebuf,
 			 ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
 {
-  pid_t pid = ptid_get_pid (inferior_ptid);
+  pid_t pid = get_ptrace_pid (inferior_ptid);
 
   switch (object)
     {
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 73ef2d4947..dff0da568a 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -3890,7 +3890,6 @@  linux_nat_xfer_partial (struct target_ops *ops, enum target_object object,
 			const gdb_byte *writebuf,
 			ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
 {
-  struct cleanup *old_chain;
   enum target_xfer_status xfer;
 
   if (object == TARGET_OBJECT_SIGNAL_INFO)
@@ -3903,15 +3902,9 @@  linux_nat_xfer_partial (struct target_ops *ops, enum target_object object,
   if (object == TARGET_OBJECT_MEMORY && ptid_equal (inferior_ptid, null_ptid))
     return TARGET_XFER_EOF;
 
-  old_chain = save_inferior_ptid ();
-
-  if (ptid_lwp_p (inferior_ptid))
-    inferior_ptid = pid_to_ptid (ptid_get_lwp (inferior_ptid));
-
   xfer = linux_ops->to_xfer_partial (ops, object, annex, readbuf, writebuf,
 				     offset, len, xfered_len);
 
-  do_cleanups (old_chain);
   return xfer;
 }
 
@@ -4001,8 +3994,8 @@  linux_proc_xfer_partial (struct target_ops *ops, enum target_object object,
 
   /* We could keep this file open and cache it - possibly one per
      thread.  That requires some juggling, but is even faster.  */
-  xsnprintf (filename, sizeof filename, "/proc/%d/mem",
-	     ptid_get_pid (inferior_ptid));
+  xsnprintf (filename, sizeof filename, "/proc/%ld/mem",
+	     ptid_get_lwp (inferior_ptid));
   fd = gdb_open_cloexec (filename, ((readbuf ? O_RDONLY : O_WRONLY)
 				    | O_LARGEFILE), 0);
   if (fd == -1)
@@ -4095,7 +4088,7 @@  linux_proc_xfer_spu (struct target_ops *ops, enum target_object object,
   char buf[128];
   int fd = 0;
   int ret = -1;
-  int pid = ptid_get_pid (inferior_ptid);
+  int pid = ptid_get_lwp (inferior_ptid);
 
   if (!annex)
     {