Re: Behaviour of default all-stop mode -- Why no one has replied ?

Pedro Alves
2009-07-21T14:00:16Z

Em Monday 20 July 2009 11:50:23, suresh ds escreveu:
> Fine. vCont is properly implemented and most of the things are working fine.
> I've a query with single step.
> Let's say there are four threads, 1,2,3,4.
> Sometimes when I single step, I get a packet from gdb as "vCont;s:1;c".
> Accordingly, I insert a break at the next address, and continue all.
>
> 1)
>
> (i) Now, even before thread 1 hits the break at the next address, the other thread(s) may hit some other breakpoint and report that. In this case, the single step is not yet
> reached (and therefore not removed). A further continue will make all run, and then thread 1 may hit this single step break, remove it and report it to gdb. What this all means
> is, gdb may get the single step status after quite some time and not immediately after one does "step". Is this OK ?

Take this sequence:

1. --> vCont;s:1;c
2. <-- T05 thread:2
3. --> vCont;c

In this case, point 3 told thread 1 to continue, so any previous step
request to thread 1 is cancelled. What is means is that the last
command applied to a thread is what counts. Even this could happen:

1. --> vCont;s:1;c
2. <-- T05 thread:2
3. --> <change PC of thread 1 to point somewhere else>
4. --> vCont;s:1

Notice that the step in point 4 is now done at a different PC
from point 1. Again, a new command to thread 1 cancelled a
previous command to thread 1.

(warning: older GDB's didn't behave correctly in this use case)

> (ii) There is also another possibility. Some other thread may hit this single step breakpoint, remove the breakpoint and report it than the actual thread 1, which is supposed
> to hit, remove it and report it. If this happens, then the actuaI thread 1 which is supposed to single step will not be single stepped. Is this way of implementation OK ?

No, it is not. GDB would report a SIGTRAP to the user, as it
had no idea why did the thread stop. And then again, neither would
the user know why did the thread stop if it didn't tell it to. It
would be a confusing behaviour. If you want to implement software single
stepping yourself, then you need to make sure that GDB doesn't see that
other threads can hit that thread-1-specific-internal-detail-to-your-stub
breakpoint. It's as if you need to make GDB believe that your architecture
supports hardware single-stepping.

> 2) Another way is, even if other threads hit some other breakpoint or hit this single step breakpoint itself, they do not report it and wait for thread 1 to hit the single step
> and report it. Is this the way to be implemented ?

That's one way. Another way is to make the thread that hit the
other-thread's-step-breakpoint "step over" the breakpoint (remove breaks; step
*only* that thread, leaving others stopped; reinsert breaks; resume threads
again, going on waiting for the right thread to reach the step
breakpoint) --- this is an implementation that avoids more than one
level deep nested software single stepping, and is what GDB implements itself
(see src/gdb/infrun.c and look around for stepping_past_singlestep_breakpoint).
You could even go crazy and support a fully nested algorithm, by *only* removing
the step-breakpoint that the thread is trying to step over, and resume all
threads that GDB asked to be running *except* the thread that *was supposed*
to hit that step-breakpoint (otherwise, that thread may well miss its step break).
Your version would be what I'd call a 0-level nesting implementation; gdb's a
1-level nesting, the latter a more complicated N-level nesting version.

--
Pedro Alves