[PR,gdb/23077] Fix error 'Couldn't get registers: Device busy' on FreeBSD
Commit Message
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
Comments
Pedro,
I tested your patch it works on FreeBSD.
No error message after attach.
Thanks
Rajendra
On Fri, Apr 20, 2018 at 7:01 PM, Pedro Alves <palves@redhat.com> wrote:
> 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(-)
@@ -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 ();
}
@@ -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