This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [PATCH] [PR gdb/13463] linux-nat: Stop lwp before xfer if running
- From: Pedro Alves <palves at redhat dot com>
- To: Simon Marchi <simon dot marchi at polymtl dot ca>
- Cc: gdb-patches at sourceware dot org
- Date: Mon, 02 Sep 2013 20:03:18 +0100
- Subject: Re: [PATCH] [PR gdb/13463] linux-nat: Stop lwp before xfer if running
- Authentication-results: sourceware.org; auth=none
- References: <5203f8bd dot SBEnufg91ES5VgBo%simon dot marchi at polymtl dot ca> <521CFEFC dot 5050008 at redhat dot com> <CAFXXi0mpTxwFosB8WDvWWZ8K5EcJyY3gx16dDB8PtuvrEefVHA at mail dot gmail dot com>
On 08/30/2013 01:48 PM, Simon Marchi wrote:
> On 27 August 2013 15:33, Pedro Alves <palves@redhat.com> wrote:
>> On 08/08/2013 08:59 PM, simon.marchi@polymtl.ca wrote:
>>> (err, resending with setting From: correctly, sorry about that)
>>>
>>> Hi,
>>>
>>> This is an attempt at finding a solution for PR 13463:
>>> http://sourceware.org/bugzilla/show_bug.cgi?id=13463
>>>
>>> IMO, this is a serious bug (at least on x86 Linux). Inserting breakpoints
>>> while the inferior is running does not work. It can be triggered very easily:
>>>
>>> 1. Start a simple program in non-stop/async mode.
>>> 2. Put a breakpoint anywhere in the program.
>>>
>>> You should get an error like
>>>
>>> Cannot access memory at address 0x400504
>>>
>>> What happens is that GDB tries to ptrace read/write the inferior's memory
>>> while the process is not stopped, which is not supported.
>>>
>>> The obvious/naive solution is to stop the process and resume it whenever
>>> we want to do a memory transfer while it is executing.
>>
>> Yeah, gdbserver does this. Starts with prepare_to_access_memory. A
>> prepare -> do -> "unprepare" sequence is possibly more efficient,
>> as we can batch several "do"s over a single pause sequence. I've considered
>> before pushing that prepare/unprepare sequence all the way to gdb core,
>> in order to batch e.g., the whole of prologue analysis + breakpoint
>> insertion, or of shared library list reading, etc., but I thought all
>> the way through all that.
>
> I saw the gdbserver version, it seems to be handled quite cleanly.
> Should I add an equivalent to prepare_to_access_memory to gdb? This
> way other platforms could do apply the same fix if the bug applies to
> them.
I think we could try that.
> Either way, this gives me a sense of the code duplication
> between gdb and gdbserver. Scary!
Yeah... http://sourceware.org/gdb/wiki/LocalRemoteFeatureParity
>
>>> I gave it a shot,
>>> and it seems to work for me, but there is probably some cases it does not
>>> cover, maybe other things it breaks or some better way to do it. I ran a
>>> make check and gdb.sum was identical before and after (minus the time).
>>
>> Points I believe should be handled:
>>
>> - it should not resume threads that were meant to be stopped,
>> or were already stopped. target_resume blindly does that.
>
> I believe my fix handles already stopped threads correctly. If the
> thread is meant to be stopped, should I simply stop it and not resume
> it after, will it be in a valid state?
Supposedly, it'll end up with a cached state that will be
reported later (and something will wake up the event loop,
resulting in a target_wait call to collect the status).
But please confirm.
> What is the right way to check
> if a thread is meant to be stopped?
Same as GDBserver. last_resume_kind will be resume_stop. You'll
see that right after "interrupt"/target_stop, and before the LWP
actually reporting a stop to target_wait.
>
>> - it's quite possible the thread you just tried to stop
>> disappears/exit just as you tried to stop it, and then the
>> xfer fails.
>>
>> On the latter issue, and considering that there's no real
>> guarantee some other thread could be simultaneously poking
>> the same address gdbserver is (there's no ptrace atomic write),
>> gdbserver takes the easy route and always pauses all threads.
>> (the opposite end of the scale would be if gdb/gdbserver
>> force-cloned a thread in the inferior to use it as proxy to
>> peek/poke through.)
>
> I wouldn't consider it a critical bug if the read/write failed because
> the thread stopped right before we peek/poke it, as it does not
> "break" a feature. I suppose it could be addressed in a different
> patch.
Not sure I follow. Did you mean if the thread "exited" instead
of "stopped"? I don't see why that'd be part of a separate patch.
It seems quite related to me.
--
Pedro Alves