The workaround I applied was to always switch to the last stopped thread
before resuming the target (which was the behaviour of GDB in versions
earlier than 6.8 - I cannot remember which). Unfortunately this
workaround as implemented for GDB 6.8 no longer works in GDB 7.0 (due to
the extensive changes) and I am in a quandary as to how to proceed.
As an experiment I checked to see what GDB 7.0 does normally without my
workaround in the following, problematic, scenario:
(gdb) continue
...stops at a break point in thread N...
(gdb) thread M
...we have now selected another thread that is not N...
(gdb) stepi
...my target cannot step thread M so what to do ???...
The trace I see (with target and infrun debugging enabled) is the following:
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) = 0x9a83270 [sh4]
target_fetch_registers (sr) = 00000040 0x40000000 1073741824
target_fetch_registers (pc) = 9e170088 0x8800179e 2281707422
target_thread_architecture (Thread 3) = 0x9a83270 [sh4]
target_fetch_registers (sr) = 00000040 0x40000000 1073741824
target_fetch_registers (pc) = 9e170088 0x8800179e 2281707422
infrun: resume (step=1, signal=0), trap_expected=1
target_terminal_inferior ()
target_resume (42000000, step, 0)
infrun: wait_for_inferior (treat_exec_as_sigtrap=0)
target_wait (-1, status) = 42000000, status->kind = stopped, signal = SIGTRAP
infrun: target_wait (-1, status) =
infrun: 42000000 [Thread 3],
infrun: status->kind = stopped, signal = SIGTRAP
target_thread_architecture (Thread 3) = 0x9a83270 [sh4]
infrun: infwait_normal_state
infrun: TARGET_WAITKIND_STOPPED
target_fetch_registers (sr) = 00000040 0x40000000 1073741824
target_fetch_registers (pc) = a0170088 0x880017a0 2281707424
infrun: stop_pc = 0x880017a0
target_stopped_by_watchpoint () = 0
infrun: handling deferred step
target_thread_architecture (Thread 7) = 0x9a83270 [sh4]
target_fetch_registers (sr) = 00000040 0x40000000 1073741824
target_fetch_registers (pc) = 50440088 0x88004450 2281718864
infrun: resume (step=1, signal=0), trap_expected=0
target_terminal_inferior ()
target_terminal_ours ()
... a source location is displayed here ...
target_terminal_ours ()
and the following error is reported by my target's implementation of the
target_resume() method:
Cannot step 'Thread 7', please select 'Thread 3'
which is a check I added to ensure that GDB doesn't request something
that the target cannot handle.
Due to the error being thrown the above debug output is missing a log
for the final target_resume(), which if I run under a debugger I can see
has the following invocation:
target_resume (ops=<address>, ptid={pid = -1, lwp = 0, tid = 0}, step=1, signal=TARGET_SIGNAL_0)
At this point ptid is minus_one_ptid, the last stopped ptid is 'Thread
3' and the inferior_ptid is 'Thread 7'. It is my understanding that this
means that GDB wants the target to step 'Thread 7', which is not
supported and hence the error. Note that the invocation of the first
target_resume() looked like the following:
target_resume (ops=<address>, ptid={pid = 42000000, lwp = 0, tid = 3}, step=1, signal=TARGET_SIGNAL_0)
Note that the initial step of 'Thread 3' above is due to there being a
S/W breakpoint being hit when the target stopped and GDB seems to want
to step over it before stepping 'Thread 7', which I assume is intended
logic.
Now some questions :-):
* Is my interpretation of the meaning of the target_resume() parameters
still valid for GDB 7.0 ?
* If it is correct, then is there a mechanism in GDB to honour the
restrictions of my target model without me needing to re-instate my
original workaround or forcing the user to switch to the only runnable
thread ?
Any advice gratefully received.
Cheers,
Antony.