Re: Spurious SIGTRAP reported by GDB 6.8 when debugging embedded RTOS application

Antony KING
2008-08-20T18:37:37Z

[-- Attachment #1: Type: text/plain, Size: 2533 bytes --]

The answer to your question is yes, this could be a strategy to
implement what the user "expects".

However I am not certain doing this in the stub/target side is the
"right thing to do" since I do not think this problem is peculiar to my
environment (plus it need to replicate some of the event handling that
is already being performed by the main event handler of GDB). Looking at
the implementation in infrun.c/infcmd.c, it seems, and I say this with
caution :-), that with a certain amount of fettling the existing code to
implement software stepping could be modified to support this scenario.

I have yet to look into this as a possible solution since it looks like
it could take a while to implement as I am not very familiar with this
part of GDB. For the time being I think I will just report an error if
the user attempts to step a thread which is not the last stopped thread
(or automatically switch to the stopped thread before stepping) and put
this on my to do list.

Also, while I was trying to absorb the mechanics of GDB in this area,
there seemed (to my untutored eye) an inconsistency between my target
definition setting "to_has_thread_control" to "tc_none" and the
execution model of infrun.c (esp. when it comes to stepping), or have I
missed something :-) ?

FYI I have attached the output of my test case when I use GDB 6.7.1
(with "set debug infrun 1"). As you can see there is no indication that
a context switch has occurred by the step; it seems that in GDB 6.7.1
changing threads did not alter the thread to be stepped (i.e. the last
stopped thread).

Cheers,

Antony.

Pedro Alves wrote:
> On Monday 18 August 2008 19:33:34, Antony KING wrote:
>> Thanks for the definition. I had not fully grasped this aspect of the
>> target_resume interface. For my target interface only mode (1) can be
>> properly supported. Modes (2) and (4) cannot be supported at all and
>> mode (3) can only be supported by ensuring that inferior_ptid is set to
>> the last stopped thread before commencing stepping.
>>
>> [Actually mode (4) can be supported but only if ptid == last stopped
>> thread, but this is the similar to supporting mode (3).]
>>
>
> In your original example, would it work to put a special
> "switch-thread breakpoint" at the PC of thread 7, so it forces
> a thread switch on your target, and then continue hardware
> single-stepping from there when it is hit? With care,
> it seems this could be hidden entirelly on the stub/target side.
>
> (I'm still curious on how this worked on 6.7.1 though)

[-- Attachment #2: gdb671.log --]
[-- Type: text/plain, Size: 2541 bytes --]

(gdb) set debug infrun 1
(gdb) tbreak mytaskfunc
Breakpoint 1 at <location>
infrun: proceed (addr=0xffffffff, signal=144, step=0)
(gdb) continue
infrun: resume (step=0, signal=0)
infrun: wait_for_inferior
Hello from OS21 root; before task_create
Hello from OS21 root; after task_create
infrun: infwait_normal_state
infrun: TARGET_WAITKIND_STOPPED
infrun: stop_pc = 0x880017a2
infrun: context switch
infrun: Switching context from Thread 42000000 to Thread 3
infrun: BPSTAT_WHAT_STOP_NOISY
infrun: stop_stepping
[Switching to Thread 3]
mytaskfunc (p=0x0) at <location>
40 int i = (int)p;
(gdb) info thread
7 Thread 7 ("My Task") <location>
6 Thread 6 ("My Task") <location>
5 Thread 5 ("My Task") <location>
4 Thread 4 ("My Task") <location>
3 Thread 2 ("Idle Task") <location>
2 Thread 1 ("Root Task") <location>
* 1 Thread 3 ("My Task") <location>
(gdb) thread 7
[Switching to thread 7 (Thread 7)]#0 <location>
1691 {
(gdb) info thread
* 7 Thread 7 ("My Task") <location>
6 Thread 6 ("My Task") <location>
5 Thread 5 ("My Task") <location>
4 Thread 4 ("My Task") <location>
3 Thread 2 ("Idle Task") <location>
2 Thread 1 ("Root Task") <location>
1 Thread 3 ("My Task") <location>
infrun: proceed (addr=0xffffffff, signal=144, step=1)
(gdb) step
infrun: resume (step=1, signal=0)
infrun: wait_for_inferior
infrun: infwait_normal_state
infrun: TARGET_WAITKIND_STOPPED
infrun: stop_pc = 0x880017a4
infrun: keep going
infrun: resume (step=1, signal=0)
infrun: prepare_to_wait
infrun: infwait_normal_state
infrun: TARGET_WAITKIND_STOPPED
infrun: stop_pc = 0x880017a6
infrun: stepping inside range [0x880017a2-0x880017ae]
infrun: resume (step=1, signal=0)
infrun: prepare_to_wait
infrun: infwait_normal_state
infrun: TARGET_WAITKIND_STOPPED
infrun: stop_pc = 0x880017a8
infrun: stepping inside range [0x880017a2-0x880017ae]
infrun: resume (step=1, signal=0)
infrun: prepare_to_wait
infrun: infwait_normal_state
infrun: TARGET_WAITKIND_STOPPED
infrun: stop_pc = 0x880017aa
infrun: stepping inside range [0x880017a2-0x880017ae]
infrun: resume (step=1, signal=0)
infrun: prepare_to_wait
infrun: infwait_normal_state
infrun: TARGET_WAITKIND_STOPPED
infrun: stop_pc = 0x880017ac
infrun: stepping inside range [0x880017a2-0x880017ae]
infrun: resume (step=1, signal=0)
infrun: prepare_to_wait
infrun: infwait_normal_state
infrun: TARGET_WAITKIND_STOPPED
infrun: stop_pc = 0x880017ae
infrun: stepped to a different line
infrun: stop_stepping
mytaskfunc (p=0x0) at <location>
41 printf("Hello from task %d\n", i);