Unneeded displaced single stepping causes issues: Performance drop and range stepping killer

Raphael Zulliger zulliger@indel.ch
Wed Apr 24 06:58:00 GMT 2013

On 04/23/2013 09:03 PM, Pedro Alves wrote:
> On 04/22/2013 11:54 AM, Raphael Zulliger wrote:
>> According to my current understanding (please correct me if I'm wrong): Range stepping decides whether to send a 'vCont;r' package by comparing the current program counter with the range that needs to be executed (control.step_range_start and control.step_range_end). Using displaced single stepping means that the program counter is, by definition, always outside the range that needs to be single stepped and thus 'range stepping' will never be used.
> I've been hacking on the range stepping series, and I've actually
> changed how GDB decides to issue a range-step or not.
> By "PC-is-in-range" has problems.  But, that's largely unrelated.
> The root issue is the forced displaced step, and that'll remain
> the same.
If you have something working, I'd like to try it out.
>> What causes the problem?
>> The following statement (from infrun.c, resume(), git master) decides whether to use displaced single stepping or not:
>>    if (use_displaced_stepping (gdbarch)
>>        && (tp->control.trap_expected
>>        || (step && gdbarch_software_single_step_p (gdbarch)))
>>        && sig == GDB_SIGNAL_0
>>        && !current_inferior ()->waiting_for_vfork_done)
>> According to my experiments:
>>      - Using gdb/gdbserver on x86/64, that statement is 'true' when we step over a breakpoint, but is 'false' otherwise ->range stepping is used when possible
>>      - Using extended remote to ppc603/EABI embedded system, that statement is always 'true' when we step because 'gdbarch_software_single_step_p' returns 'true' ->range stepping is never used
>>      - When patching GDB so that 'gdbarch->software_single_step = NULL', then the behavior is like on x86/64 and thus 'range stepping' works ->range stepping is used when possible
>> Finally, my request: Could someone with more insight into GDB internals please decide whether we have to fix something here and if yes, how? Or, in case that my conclusions are wrong, could you help me to really understand the problem? (FYI: My ultimate goal is to speedup remote debugging for our ppc603/EABI target.)
> There are several things to consider here.  The
> "(step && gdbarch_software_single_step_p (gdbarch))" part
> was added because GDB can't currently do multiple software
> single-steps simultaneously, which is a problem for non-stop
> mode (which enables displaced stepping).  The workaround was to force
> displaced stepping for all single-steps.  GDB knows how to queue
> displaced step requests (necessary because there's only one scratch
> pad for all threads), and have threads wait for their turn in the
> queue.  I was working on making GDB aware of multiple software
> single-steps a while ago, but I got distracted with other things
> and haven't finished that yet...
Thanks for this useful clarification. (Unfortunately, it
was not obvious to me by reading the code)
> Then, as you note, gdbarch_software_single_step_p isn't really the
> right predicate.  A better one would be "do I need to software
> single-step this instruction".  There's no such predicate today,
> because the gdbarch_software_single_step hook is responsible for
> installing the breakpoints itself, instead of returning a vector
> of the locations where breakpoints should be set (which I think
> would be better).
Sounds good.

More information about the Gdb mailing list