This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [PATCH] [PR gdb/23077] Fix error 'Couldn't get registers: Device busy' on FreeBSD
- From: Pedro Alves <palves at redhat dot com>
- To: Rajendra SY <rajendra dot sy at gmail dot com>, gdb-patches at sourceware dot org
- Date: Fri, 20 Apr 2018 14:31:54 +0100
- Subject: Re: [PATCH] [PR gdb/23077] Fix error 'Couldn't get registers: Device busy' on FreeBSD
- References: <CAMAnt0=eSyFzJybVAXFUrv8MSNUX3mCi5AwOozs3XK0c4Uti2w@mail.gmail.com>
On 04/20/2018 10:46 AM, Rajendra SY wrote:
> <patch attached>
>
> Problem:
> GDB "attach pid" command shows error message "Couldn't get registers:
> Device busy" because of which below gdb tests fail.
>
> Cause:
> On FreeBSD ptrace() syscall requires LWP id to fetch info from the
> inferior process.
> The current implementation is every command is executed completely and
> then it wait's for asynchronous events.
>
> When attach command is executed it calls inf_ptrace_attach() function
> which is currently doing just the ptrace(PT_ATTACH), it does not wait
> for the process to stop to fetch LWP info.
> The fbsd_wait() function is the one which fetches LWP info which is
> being called after the command completes.
>
> Command execution code flow -
> gdb_do_one_event() => .. => handle_file_event() => .. =>
> execute_command() => check_frame_language_change()
>
> The async event handling code flow where LWP info gets updated -
> gdb_one_event() => check_async_event_handlers() => ..
> ->do_target_wait() => .. => fbsd_wait()
>
> The check, if the frame language changed via
> check_frame_language_change() function is trying to read registers
> using ptrace(pid) which fails because LWP id is not fetched.
>
> The purposed patch tries to avoid this situation by avoiding calling
> check_frame_language_change() function just for the "attach" command.
>
Thanks for the patch, but we need to find a better fix.
It seems to me that the problem is that we fail to mark
the thread as executing between the initial attach, and the
subsequent target_wait. Can you give the attached patch a try?
check_frame_language_change() then becomes a nop until
the thread is marked not-executing again, after target_wait
is called.
We don't see the problem on Linux because there, the target_attach
implementation waits for the thread to stop before returning.
Still, that's supposedly hidden from the core, since the Linux
target, like most targets, is a '!to_attach_no_wait' target.
Pedro Alves
>From d1a0ee089d0d59af19fd65267e0e1d2f5f7821c0 Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Fri, 20 Apr 2018 12:22:05 +0100
Subject: [PATCH] Mark just-attached-to thread as executing
---
gdb/inf-ptrace.c | 3 ++-
gdb/remote.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/gdb/inf-ptrace.c b/gdb/inf-ptrace.c
index e20388658fe..68d557138a0 100644
--- a/gdb/inf-ptrace.c
+++ b/gdb/inf-ptrace.c
@@ -235,7 +235,8 @@ inf_ptrace_attach (struct target_ops *ops, const char *args, int from_tty)
/* Always add a main thread. If some target extends the ptrace
target, it should decorate the ptid later with more info. */
- add_thread_silent (inferior_ptid);
+ thread_info *tp = add_thread_silent (inferior_ptid);
+ set_executing (tp->ptid, true);
unpusher.release ();
}
diff --git a/gdb/remote.c b/gdb/remote.c
index f54a38833b3..dc1c62f214c 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -5316,7 +5316,8 @@ extended_remote_attach (struct target_ops *target, const char *args,
inferior_ptid = remote_current_thread (inferior_ptid);
/* Add the main thread to the thread list. */
- add_thread_silent (inferior_ptid);
+ thread_info *tp = add_thread_silent (inferior_ptid);
+ set_executing (tp->ptid, true);
}
/* Next, if the target can specify a description, read it. We do
--
2.14.3