This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] [PR gdb/23077] Fix error 'Couldn't get registers: Device busy' on FreeBSD


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]