I noticed that in all stop mode, GDB expects the current Hg thread to be changed to the thread reported in the stop reply message, without sending an Hg command. This can most easily be seen by using the "i threads" command. GDB will read the registers of each (non-current) thread using 'Hg' / 'g', so it can display the PC location in the threads list. However, after a stop message, GDB appears to assume that the Hg thread is set to the current thread, even though it changed the Hg thread during 'i threads'. I could not find where this was documented. The 'fix' for me was to assume both Hg and Hc are auto-changed to whatever thread is reported in the stop reply when in all-stop mode. Here is an example (reusing it from my other e-mail question): (gdb) thread 3 [Switching to thread 3 (Thread 3)] (gdb) c& Continuing. (gdb) interrupt Thread 3 received signal SIGINT, Interrupt. (gdb) i threads Id Target Id Frame 1 Thread 1 (ACTIVE) startup () at r5_tests/c_test/boot.S:12 2 Thread 2 (ACTIVE) startup () at r5_tests/c_test/boot.S:13 * 3 Thread 3 (ACTIVE) startup () at r5_tests/c_test/boot.S:14 4 Thread 4 (ACTIVE) startup () at r5_tests/c_test/boot.S:15 (gdb) c& Continuing. (gdb) interrupt Thread 3 received signal SIGINT, Interrupt. GDB Remote Server Log: ==================== // When I first swap to thread 3, GDB first sends 'T3' 'T3' ---> <--- '$OK#9a' // Then GDB sends 'Hg3' so it can read the registers 'Hg3' ---> <--- '$OK#9a' 'g' ---> <--- '$0000000000000000000000000000000000000000000000000000000000...' 'vCont;c' ---> 'Ctrl-C' ---> <--- '$T02thread:3;#d6' 'g' ---> <--- '$0000000000000000000000000000000000000000000000000000000000...' 'qfThreadInfo' ---> <--- '$m1,2,3,4#bb' 'qsThreadInfo' ---> <--- '$l#6c' 'qfThreadInfo' ---> <--- '$m1,2,3,4#bb' 'qsThreadInfo' ---> <--- '$l#6c' 'qThreadExtraInfo,1' ---> <--- '$414354495645#a9' 'qThreadExtraInfo,2' ---> <--- '$414354495645#aa' 'qThreadExtraInfo,3' ---> <--- '$414354495645#ab' 'qThreadExtraInfo,4' ---> <--- '$414354495645#ac' 'Hg1' ---> <--- '$OK#9a' 'g' ---> <--- '$0000000000000000000000000000000000000000000000000000000000...' 'Hg2' ---> <--- '$OK#9a' 'g' ---> <--- '$0000000000000000000000000000000000000000000000000000000000...' 'Hg4' ---> <--- '$OK#9a' 'g' ---> <--- '$0000000000000000000000000000000000000000000000000000000000...' 'vCont;c' ---> 'Ctrl-C' ---> // Here the server stops again on thread 3. Since GDB's current thread is 3, it does not swap threads <--- '$T02thread:3;#d6' // Here GDB is attempting to read the registers for thread 3, but the last Hg sent out was Hg4 'g' ---> <--- '$0000000000000000000000000000000000000000000000000000000000...' 'qfThreadInfo' ---> <--- '$m1,2,3,4#bb' 'qsThreadInfo' ---> <--- '$l#6c'
On 2022-04-08 16:36, Denio, Mike via Gdb wrote: > I noticed that in all stop mode, GDB expects the current Hg thread to be changed to the thread reported in the stop reply message, without sending an Hg command. This can most easily be seen by using the "i threads" command. GDB will read the registers of each (non-current) thread using 'Hg' / 'g', so it can display the PC location in the threads list. However, after a stop message, GDB appears to assume that the Hg thread is set to the current thread, even though it changed the Hg thread during 'i threads'. I could not find where this was documented. I could swear this was documented, but I can't actually find it either. This has "always" been this way, AFAIK. In GDB's remote_target::wait_as, you can see that GDB calls record_currthread to make the Hg thread match the event thread. In GDBserver, we have this, in prepare_resume_reply: /* This if (1) ought to be unnecessary. But remote_wait in GDB will claim this event belongs to inferior_ptid if we do not specify a thread, and there's no way for gdbserver to know what inferior_ptid is. */ if (1 || cs.general_thread != ptid) { int core = -1; /* In non-stop, don't change the general thread behind GDB's back. */ if (!non_stop) cs.general_thread = ptid; I actually remember running into this comment that if (1) when I started working in gdbserver, and I may have learned this from the code instead of from the manual. Non-stop was added later, and changing the current thread when an event is reported is just completely incompatible with the asynchronous way of non-stop RSP stop events, so I added that if (!non_stop). I guess I didn't realize back then that that should also be documented somewhere. If no one beats me to it, I'll clarify this in the manual when I have a chance. > > The 'fix' for me was to assume both Hg and Hc are auto-changed to whatever thread is reported in the stop reply when in all-stop mode. GDB only auto-changes the Hg thread, see record_currthread.
Thanks for the info. Its not big deal as It's something that becomes obvious with use. I just thought I'd mention it. I misspoke in my last e-mail. I forgot that I actually ignore the Hc command now and base everything on the vCont. If you have any thoughts on my other message, please let me know. For now, I'm going to rely on the 'T' command in all-stop mode to know that GDB has changed the current thread, but it would be nice if there was an official method. Mike -----Original Message----- From: Pedro Alves <pedro@palves.net> Sent: Friday, April 08, 2022 4:41 PM I could swear this was documented, but I can't actually find it either. This has "always" been this way, AFAIK. [...] GDB only auto-changes the Hg thread, see record_currthread.