Question about stepping on a target which supports multi-threading but can only step the last stopped thread

Antony KING
Fri Feb 19 17:15:00 GMT 2010

On 18/02/2010 20:40, Michael Snyder wrote:
>> As a result of upgrading to GDB 7.0 from GDB 6.8 I am having to review a
>> workaround (i.e. bodge) I made to GDB 6.8 in order to handle stepping on
>> a target which supports multi-threading but which can only single
>> instruction step the last stopped thread.
> There's a function in infrun.c called 'prepare_to_proceed' that is
> supposed to handle this situation.  Can you check and see what
> 'prepare_to_proceed' is doing with your target?

I have looked at the source and I do not think this function is doing
anything "incorrectly". To simplify, I repeated the same test as in my
original email but this time without any breakpoints enabled and I see
the following debug log:

> (gdb) stepi
> infrun: clear_proceed_status_thread (Thread 7)
> infrun: clear_proceed_status_thread (Thread 6)
> infrun: clear_proceed_status_thread (Thread 5)
> infrun: clear_proceed_status_thread (Thread 4)
> infrun: clear_proceed_status_thread (Thread 2)
> infrun: clear_proceed_status_thread (Thread 1)
> infrun: clear_proceed_status_thread (Thread 3)
> infrun: proceed (addr=0xffffffff, signal=144, step=1)
> target_thread_architecture (Thread 3) = 0x946c270 [sh4]
> target_fetch_registers (sr) = 00000040 0x40000000 1073741824
> target_fetch_registers (pc) = 9e170088 0x8800179e 2281707422
> target_thread_architecture (Thread 7) = 0x946c270 [sh4]
> infrun: resume (step=1, signal=0), trap_expected=0
> target_terminal_inferior ()
> target_terminal_ours_for_output ()
> [Switching to Thread 7]
> target_terminal_ours ()
> ... a source location is displayed here ...
> target_terminal_ours ()
> Cannot step 'Thread 7', please select 'Thread 3'
> (gdb) 

In this case it does not perform a step over the breakpoint in 'Thread
3' before trying to step 'Thread 7'.

With this simplified scenario, stepping through prepare_to_proceed() I
observed that no special handling is being performed and the function
returns with a result of 0 (as the final statement), i.e. all the
conditions tested for in the function are false.

My problem is that GDB seems to assume that a target can cope with the
requirement that is able to step any thread GDB chooses, which is not
the case for my target. That is, I cannot see any mechanism in GDB
whereby it will:

* detect that the current thread (as selected by the user using the
"thread" command) is not the active thread (i.e. the thread generated
the last stop event) and then,
* plant a breakpoint at the current PC of this thread,
* issue a continue (all threads) until this thread becomes the active
thread (by hitting this breakpoint),
* and then perform the normal stepping functionality.

Even this strategy I consider to less than ideal when debugging embedded
systems as this will result in the target state changing quite
dramatically in order to implement the step. That is, the state of the
target after the step will not actually reflect just the effects of the
statement being stepped, a lot more could have changed to the detriment
of the debugging experience. If implemented, I think a flag would be
required to allow the user override this behaviour and force stepping
(and other operations of its type) to only work with the active thread

It seems that GDB assumes that the target will take care of:

* switching the active thread to the new thread,
* and then performing the step.

which unfortunately is not possible.

If this is the case then I am therefore left with 2 options, re-instate
my workaround or throw an error (indicating that the operation is not
supported on my target) for all execution commands which are sensitive
to the selected thread (i.e. all except the "continue" command).



More information about the Gdb mailing list