[v2] Remove lwp -> pid conversion in linux_nat_xfer_partial
Commit Message
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
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
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!
@@ -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)
{
@@ -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)
{