|
|
2c2fa1 |
NOTE: This patch has been forwardported to RHEL-7.2. It is originally
|
|
|
2c2fa1 |
from RHEL-6.7.
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
Message-ID: <54E37CE7.50703@redhat.com>
|
|
|
2c2fa1 |
Date: Tue, 17 Feb 2015 17:39:51 +0000
|
|
|
2c2fa1 |
From: Pedro Alves <palves@redhat.com>
|
|
|
2c2fa1 |
To: Sergio Durigan Junior <sergiodj@redhat.com>
|
|
|
2c2fa1 |
Subject: [debug-list] [PATCH] RH BZ #1162264 - gdb/linux-nat.c:1411:
|
|
|
2c2fa1 |
internal-error:,
|
|
|
2c2fa1 |
linux_nat_post_attach_wait: Assertion `pid == new_pid' failed.
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
Hi.
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1162264
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
So I spend a few more hours today trying to reproduce the
|
|
|
2c2fa1 |
EACCES, to no avail. Also, unfortunately, none of the attach
|
|
|
2c2fa1 |
bugs exposed by attach-many-short-lived-threads.exp test
|
|
|
2c2fa1 |
can explain this.
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
It seems to be that really the best we can do is cope with
|
|
|
2c2fa1 |
the error, like in the patch below.
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
Note that the backtrace at
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
https://bugzilla.redhat.com/show_bug.cgi?id=1162264#c3 :
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
shows that this triggers for the main thread already:
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
...
|
|
|
2c2fa1 |
#6 0x000000000044fd2e in linux_nat_post_attach_wait (ptid=..., first=1, cloned=0x1d84368,
|
|
|
2c2fa1 |
...
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
(note "first=1").
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
For upstream, I think linux_nat_attach should be adjusted to work
|
|
|
2c2fa1 |
like gdbserver -- that is, leave the initial waitpid to the main
|
|
|
2c2fa1 |
wait code, like all other events, instead of synchronously
|
|
|
2c2fa1 |
doing waitpid(PID). That'll get rid of linux_nat_post_attach_wait
|
|
|
2c2fa1 |
altogether. But that's too invasive for a bug fix.
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
>From 072c61aeb9adc64e1eb45c120061b85fbf6f4d25 Mon Sep 17 00:00:00 2001
|
|
|
2c2fa1 |
From: Pedro Alves <palves@redhat.com>
|
|
|
2c2fa1 |
Date: Tue, 17 Feb 2015 17:11:05 +0000
|
|
|
2c2fa1 |
Subject: [PATCH] RH BZ #1162264 - gdb/linux-nat.c:1411: internal-error:
|
|
|
2c2fa1 |
linux_nat_post_attach_wait: Assertion `pid == new_pid' failed.
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
According to BZ #1162264, it can happen that we manage to attach to a
|
|
|
2c2fa1 |
process, but then waitpid on it fails with EACCES. That's unexpected,
|
|
|
2c2fa1 |
and gdb hits an assertion. But given this is an error that is out of
|
|
|
2c2fa1 |
our control, we should handle it gracefully. I wasn't able to
|
|
|
2c2fa1 |
reproduce the EACCES, but hacking in the error, like:
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
| --- a/gdb/linux-nat.c
|
|
|
2c2fa1 |
| +++ b/gdb/linux-nat.c
|
|
|
2c2fa1 |
| @@ -1409,7 +1409,7 @@ linux_nat_post_attach_wait (ptid_t ptid, int first, int *cloned,
|
|
|
2c2fa1 |
| *cloned = 1;
|
|
|
2c2fa1 |
| }
|
|
|
2c2fa1 |
|
|
|
|
2c2fa1 |
| - if (new_pid != pid)
|
|
|
2c2fa1 |
| + if (new_pid != pid || 1)
|
|
|
2c2fa1 |
| {
|
|
|
2c2fa1 |
| int saved_errno = errno;
|
|
|
2c2fa1 |
|
|
|
|
2c2fa1 |
| @@ -1423,6 +1423,7 @@ linux_nat_post_attach_wait (ptid_t ptid, int first, int *cloned,
|
|
|
2c2fa1 |
| ptrace (PTRACE_DETACH, pid, 0, 0);
|
|
|
2c2fa1 |
|
|
|
|
2c2fa1 |
| errno = saved_errno;
|
|
|
2c2fa1 |
| + errno = EACCES;
|
|
|
2c2fa1 |
| perror_with_name (_("waitpid"));
|
|
|
2c2fa1 |
| }
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
... I could confirm that the error handling works properly. On the
|
|
|
2c2fa1 |
EACCES case, we get:
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
(gdb) attach 1202
|
|
|
2c2fa1 |
Attaching to process 1202
|
|
|
2c2fa1 |
Unable to attach: waitpid: Permission denied.
|
|
|
2c2fa1 |
(gdb) info inferiors
|
|
|
2c2fa1 |
Num Description Executable
|
|
|
2c2fa1 |
* 1 <null>
|
|
|
2c2fa1 |
(gdb)
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
No test because the conditions that lead to the waitpid error are
|
|
|
2c2fa1 |
unknown.
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
gdb/ChangeLog:
|
|
|
2c2fa1 |
2015-02-17 Pedro Alves <palves@redhat.com>
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
* linux-nat.c: Include "exceptions.h".
|
|
|
2c2fa1 |
(linux_nat_post_attach_wait): If waitpid returns an excepted
|
|
|
2c2fa1 |
result, detach and error out instead of asserting.
|
|
|
2c2fa1 |
(linux_nat_attach): Wrap linux_nat_post_attach_wait in TRY_CATCH.
|
|
|
2c2fa1 |
Mourn inferior and rethrow in case of error while waiting for the
|
|
|
2c2fa1 |
initial stop.
|
|
|
2c2fa1 |
---
|
|
|
2c2fa1 |
gdb/linux-nat.c | 34 +++++++++++++++++++++++++++++++---
|
|
|
2c2fa1 |
1 file changed, 31 insertions(+), 3 deletions(-)
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
Index: gdb-7.6.1/gdb/linux-nat.c
|
|
|
2c2fa1 |
===================================================================
|
|
|
2c2fa1 |
--- gdb-7.6.1.orig/gdb/linux-nat.c
|
|
|
2c2fa1 |
+++ gdb-7.6.1/gdb/linux-nat.c
|
|
|
2c2fa1 |
@@ -1397,7 +1397,22 @@ linux_nat_post_attach_wait (ptid_t ptid,
|
|
|
2c2fa1 |
*cloned = 1;
|
|
|
2c2fa1 |
}
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
- gdb_assert (pid == new_pid);
|
|
|
2c2fa1 |
+ if (new_pid != pid)
|
|
|
2c2fa1 |
+ {
|
|
|
2c2fa1 |
+ int saved_errno = errno;
|
|
|
2c2fa1 |
+
|
|
|
2c2fa1 |
+ /* Unexpected waitpid result. EACCES has been observed on RHEL
|
|
|
2c2fa1 |
+ 6.5 (RH BZ #1162264). This is most likely a kernel bug, thus
|
|
|
2c2fa1 |
+ out of our control, so treat it as invalid input. The LWP's
|
|
|
2c2fa1 |
+ state is indeterminate at this point, so best we can do is
|
|
|
2c2fa1 |
+ error out, otherwise we'd probably end up wedged later on.
|
|
|
2c2fa1 |
+
|
|
|
2c2fa1 |
+ In case we're still attached. */
|
|
|
2c2fa1 |
+ ptrace (PTRACE_DETACH, pid, 0, 0);
|
|
|
2c2fa1 |
+
|
|
|
2c2fa1 |
+ errno = saved_errno;
|
|
|
2c2fa1 |
+ perror_with_name (_("waitpid"));
|
|
|
2c2fa1 |
+ }
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
if (!WIFSTOPPED (status))
|
|
|
2c2fa1 |
{
|
|
|
2c2fa1 |
@@ -1621,7 +1636,7 @@ static void
|
|
|
2c2fa1 |
linux_nat_attach (struct target_ops *ops, char *args, int from_tty)
|
|
|
2c2fa1 |
{
|
|
|
2c2fa1 |
struct lwp_info *lp;
|
|
|
2c2fa1 |
- int status;
|
|
|
2c2fa1 |
+ int status = 0;
|
|
|
2c2fa1 |
ptid_t ptid;
|
|
|
2c2fa1 |
volatile struct gdb_exception ex;
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
@@ -1659,8 +1674,19 @@ linux_nat_attach (struct target_ops *ops
|
|
|
2c2fa1 |
/* Add the initial process as the first LWP to the list. */
|
|
|
2c2fa1 |
lp = add_initial_lwp (ptid);
|
|
|
2c2fa1 |
|
|
|
2c2fa1 |
- status = linux_nat_post_attach_wait (lp->ptid, 1, &lp->cloned,
|
|
|
2c2fa1 |
- &lp->signalled);
|
|
|
2c2fa1 |
+ TRY_CATCH (ex, RETURN_MASK_ERROR)
|
|
|
2c2fa1 |
+ {
|
|
|
2c2fa1 |
+ status = linux_nat_post_attach_wait (lp->ptid, 1, &lp->cloned,
|
|
|
2c2fa1 |
+ &lp->signalled);
|
|
|
2c2fa1 |
+ }
|
|
|
2c2fa1 |
+ if (ex.reason < 0)
|
|
|
2c2fa1 |
+ {
|
|
|
2c2fa1 |
+ target_terminal_ours ();
|
|
|
2c2fa1 |
+ target_mourn_inferior ();
|
|
|
2c2fa1 |
+
|
|
|
2c2fa1 |
+ error (_("Unable to attach: %s"), ex.message);
|
|
|
2c2fa1 |
+ }
|
|
|
2c2fa1 |
+
|
|
|
2c2fa1 |
if (!WIFSTOPPED (status))
|
|
|
2c2fa1 |
{
|
|
|
2c2fa1 |
if (WIFEXITED (status))
|