Open danlehmann opened 1 month ago
To show the problem, this is the trace when connecting to the short target_description_xml in my risc-v 32 bit emulator:
TRACE gdbstub::protocol::recv_packet > <-- +
TRACE gdbstub::protocol::recv_packet > <-- $QStartNoAckMode#b0
TRACE gdbstub::protocol::response_writer > --> $OK#9a
TRACE gdbstub::protocol::recv_packet > <-- +
TRACE gdbstub::protocol::recv_packet > <-- $qSupported:xmlRegisters=i386,arm,mips,arc;multiprocess+;fork-events+;vfork-events+#2e
TRACE gdbstub::protocol::response_writer > --> $PacketSize=1000;vContSupported+;multiprocess+;QStartNoAckMode+;swbreak+;qXfer:features:read+#fd
TRACE gdbstub::protocol::recv_packet > <-- $QThreadSuffixSupported#e4
INFO gdbstub::stub::core_impl > Unknown command: Ok("QThreadSuffixSupported")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $QListThreadsInStopReply#21
INFO gdbstub::stub::core_impl > Unknown command: Ok("QListThreadsInStopReply")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $vCont?#49
TRACE gdbstub::protocol::response_writer > --> $vCont;c;C;s;S#62
TRACE gdbstub::protocol::recv_packet > <-- $qVAttachOrWaitSupported#38
INFO gdbstub::stub::core_impl > Unknown command: Ok("qVAttachOrWaitSupported")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $QEnableErrorStrings#8c
INFO gdbstub::stub::core_impl > Unknown command: Ok("QEnableErrorStrings")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $qHostInfo#9b
INFO gdbstub::stub::core_impl > Unknown command: Ok("qHostInfo")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $qProcessInfo#dc
INFO gdbstub::stub::core_impl > Unknown command: Ok("qProcessInfo")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $qC#b4
INFO gdbstub::stub::core_impl > Unknown command: Ok("qC")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $qfThreadInfo#bb
TRACE gdbstub::protocol::response_writer > --> $mp01.01#cd
TRACE gdbstub::protocol::recv_packet > <-- $qsThreadInfo#c8
TRACE gdbstub::protocol::response_writer > --> $l#6c
TRACE gdbstub::protocol::recv_packet > <-- $?#3f
TRACE gdbstub::protocol::response_writer > --> $T05thread:p01.01;#06
TRACE gdbstub::protocol::recv_packet > <-- $qProcessInfo#dc
INFO gdbstub::stub::core_impl > Unknown command: Ok("qProcessInfo")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $qXfer:features:read:target.xml:0,fff#7d
TRACE gdbstub::protocol::response_writer > --> $m<target version="1.0"><architecture>riscv:rv32</architecture></target>#ab
TRACE gdbstub::protocol::recv_packet > <-- $qXfer:features:read:target.xml:46,fff#b7
TRACE gdbstub::protocol::response_writer > --> $l#6c
TRACE gdbstub::protocol::recv_packet > <-- $qRegisterInfo0#72
INFO gdbstub::stub::core_impl > Unknown command: Ok("qRegisterInfo0")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $Hg1#e0
TRACE gdbstub::protocol::response_writer > --> $OK#9a
TRACE gdbstub::protocol::recv_packet > <-- $p0#a0
INFO gdbstub::stub::core_impl > Unknown command: Ok("p0")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $qProcessInfo#dc
INFO gdbstub::stub::core_impl > Unknown command: Ok("qProcessInfo")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $qProcessInfo#dc
INFO gdbstub::stub::core_impl > Unknown command: Ok("qProcessInfo")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $qProcessInfo#dc
INFO gdbstub::stub::core_impl > Unknown command: Ok("qProcessInfo")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $qOffsets#4b
INFO gdbstub::stub::core_impl > Unknown command: Ok("qOffsets")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $qStructuredDataPlugins#02
INFO gdbstub::stub::core_impl > Unknown command: Ok("qStructuredDataPlugins")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $qSymbol::#5b
INFO gdbstub::stub::core_impl > Unknown command: Ok("qSymbol::")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $qfThreadInfo#bb
TRACE gdbstub::protocol::response_writer > --> $mp01.01#cd
TRACE gdbstub::protocol::recv_packet > <-- $qsThreadInfo#c8
TRACE gdbstub::protocol::response_writer > --> $l#6c
TRACE gdbstub::protocol::recv_packet > <-- $jThreadsInfo#c1
INFO gdbstub::stub::core_impl > Unknown command: Ok("jThreadsInfo")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $jThreadExtendedInfo:#b9
INFO gdbstub::stub::core_impl > Unknown command: Ok("jThreadExtendedInfo:")
TRACE gdbstub::protocol::response_writer > --> $#00
Registers are never queried.
Once I add the registers, things look as expected:
TRACE gdbstub::protocol::recv_packet > <-- +
TRACE gdbstub::protocol::recv_packet > <-- $QStartNoAckMode#b0
TRACE gdbstub::protocol::response_writer > --> $OK#9a
TRACE gdbstub::protocol::recv_packet > <-- +
TRACE gdbstub::protocol::recv_packet > <-- $qSupported:xmlRegisters=i386,arm,mips,arc;multiprocess+;fork-events+;vfork-events+#2e
TRACE gdbstub::protocol::response_writer > --> $PacketSize=1000;vContSupported+;multiprocess+;QStartNoAckMode+;swbreak+;qXfer:features:read+#fd
TRACE gdbstub::protocol::recv_packet > <-- $QThreadSuffixSupported#e4
INFO gdbstub::stub::core_impl > Unknown command: Ok("QThreadSuffixSupported")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $QListThreadsInStopReply#21
INFO gdbstub::stub::core_impl > Unknown command: Ok("QListThreadsInStopReply")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $vCont?#49
TRACE gdbstub::protocol::response_writer > --> $vCont;c;C;s;S#62
TRACE gdbstub::protocol::recv_packet > <-- $qVAttachOrWaitSupported#38
INFO gdbstub::stub::core_impl > Unknown command: Ok("qVAttachOrWaitSupported")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $QEnableErrorStrings#8c
INFO gdbstub::stub::core_impl > Unknown command: Ok("QEnableErrorStrings")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $qHostInfo#9b
INFO gdbstub::stub::core_impl > Unknown command: Ok("qHostInfo")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $qProcessInfo#dc
INFO gdbstub::stub::core_impl > Unknown command: Ok("qProcessInfo")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $qC#b4
INFO gdbstub::stub::core_impl > Unknown command: Ok("qC")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $qfThreadInfo#bb
TRACE gdbstub::protocol::response_writer > --> $mp01.01#cd
TRACE gdbstub::protocol::recv_packet > <-- $qsThreadInfo#c8
TRACE gdbstub::protocol::response_writer > --> $l#6c
TRACE gdbstub::protocol::recv_packet > <-- $?#3f
TRACE gdbstub::protocol::response_writer > --> $T05thread:p01.01;#06
TRACE gdbstub::protocol::recv_packet > <-- $qProcessInfo#dc
INFO gdbstub::stub::core_impl > Unknown command: Ok("qProcessInfo")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $qXfer:features:read:target.xml:0,fff#7d
TRACE gdbstub::protocol::response_writer > --> $m<target version="1.0">
<architecture>riscv:rv32</architecture>
<feature name="org.gnu.gdb.riscv.cpu">
<reg name="zero" bitsize="32" type="int" regnum="0"/>
<reg name="ra" bitsize="32" type="code_ptr"/>
<reg name="sp" bitsize="32" type="data_ptr"/>
<reg name="gp" bitsize="32" type="data_ptr"/>
<reg name="tp" bitsize="32" type="data_ptr"/>
<reg name="t0" bitsize="32" type="int"/>
<reg name="t1" bitsize="32" type="int"/>
<reg name="t2" bitsize="32" type="int"/>
<reg name="fp" bitsize="32" type="data_ptr"/>
<reg name="s1" bitsize="32" type="int"/>
<reg name="a0" bitsize="32" type="int"/>
<reg name="a1" bitsize="32" type="int"/>
<reg name="a2" bitsize="32" type="int"/>
<reg name="a3" bitsize="32" type="int"/>
<reg name="a4" bitsize="32" type="int"/>
<reg name="a5" bitsize="32" type="int"/>
<reg name="a6" bitsize="32" type="int"/>
<reg name="a7" bitsize="32" type="int"/>
<reg name="s2" bitsize="32" type="int"/>
<reg name="s3" bitsize="32" type="int"/>
<reg name="s4" bitsize="32" type="int"/>
<reg name="s5" bitsize="32" type="int"/>
<reg name="s6" bitsize="32" type="int"/>
<reg name="s7" bitsize="32" type="int"/>
<reg name="s8" bitsize="32" type="int"/>
<reg name="s9" bitsize="32" type="int"/>
<reg name="s10" bitsize="32" type="int"/>
<reg name="s11" bitsize="32" type="int"/>
<reg name="t3" bitsize="32" type="int"/>
<reg name="t4" bitsize="32" type="int"/>
<reg name="t5" bitsize="32" type="int"/>
<reg name="t6" bitsize="32" type="int"/>
<reg name="pc" bitsize="32" type="code_ptr"/>
</feature>
</target>#50
TRACE gdbstub::protocol::recv_packet > <-- $qXfer:features:read:target.xml:632,fff#e8
TRACE gdbstub::protocol::response_writer > --> $l#6c
TRACE gdbstub::protocol::recv_packet > <-- $Hg1#e0
TRACE gdbstub::protocol::response_writer > --> $OK#9a
TRACE gdbstub::protocol::recv_packet > <-- $p0#a0
INFO gdbstub::stub::core_impl > Unknown command: Ok("p0")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $qProcessInfo#dc
INFO gdbstub::stub::core_impl > Unknown command: Ok("qProcessInfo")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $qProcessInfo#dc
INFO gdbstub::stub::core_impl > Unknown command: Ok("qProcessInfo")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $qProcessInfo#dc
INFO gdbstub::stub::core_impl > Unknown command: Ok("qProcessInfo")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $qOffsets#4b
INFO gdbstub::stub::core_impl > Unknown command: Ok("qOffsets")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $qStructuredDataPlugins#02
INFO gdbstub::stub::core_impl > Unknown command: Ok("qStructuredDataPlugins")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $qSymbol::#5b
INFO gdbstub::stub::core_impl > Unknown command: Ok("qSymbol::")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $qfThreadInfo#bb
TRACE gdbstub::protocol::response_writer > --> $mp01.01#cd
TRACE gdbstub::protocol::recv_packet > <-- $qsThreadInfo#c8
TRACE gdbstub::protocol::response_writer > --> $l#6c
TRACE gdbstub::protocol::recv_packet > <-- $g#67
TRACE gdbstub::protocol::response_writer > --> $000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042#ce
TRACE gdbstub::protocol::recv_packet > <-- $qMemoryRegionInfo:42000000#9a
INFO gdbstub::stub::core_impl > Unknown command: Ok("qMemoryRegionInfo:42000000")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $jThreadsInfo#c1
INFO gdbstub::stub::core_impl > Unknown command: Ok("jThreadsInfo")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $jThreadExtendedInfo:#b9
INFO gdbstub::stub::core_impl > Unknown command: Ok("jThreadExtendedInfo:")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $x0,0#04
INFO gdbstub::stub::core_impl > Unknown command: Ok("x0,0")
TRACE gdbstub::protocol::response_writer > --> $#00
TRACE gdbstub::protocol::recv_packet > <-- $m42000000,200#b1
TRACE gdbstub::protocol::response_writer > --> $1711c8fd130101001725c8fd1305852497a5c8fd938585216307b500232005001105e34db5fe1715c8fd1305a5fd9725c8fd9385252217d61d001306a69c6308b500044204c111051106e34cb5fe97d00700e78060f8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000097501300e780007d2571232e1118232c8118232a91182328211923263119232441192322511923206119232e7117232c8117232a91172328a1172326b1170013ae892324a4e63705fdfc130ac5cf37f5f0f0930a050f37c5c0c0130b050c37050303930b3530130cc4e69304c4e8130600142685814597701900e780801d814c03c5190083c5090003c6290083c6390022054d8d4206e206558e518d83c5590003c6490083c6690003c77900a205d18dc2066207d98ed58d03c6990083c6890003c7a90083c7b9002206558e4207e2075d8f598e83c6d90003c7c90083c7e90003c8f900a206d98ec20762083367f800d98e13571500298fb757555593875755#0a
Reviewing the GDB RSP spec (at https://sourceware.org/gdb/current/onlinedocs/gdb.html/Target-Description-Format.html#Target-Description-Format), it does seem that gdbstub_arch
is technically allowed to send over just the architecture
string.
That's not to say this is strictly the best idea. If upstream GDB changes the built-in target.xml structure for an architecture, gdbstub_arch
could go out-of-sync, and send registers over in the wrong order. While it does seem that GDB make those sorts of breaking changes often (if ever), its always possible they might...
In any case - I'm not at all surprised that lldb might not be a fan of getting a "partial" XML like this, as presumably, most other GDB stubs will either send over no target.xml at all, or send over a fully-featured target.xml in its entirety.
I think its quite reasonable that gdbstub_arch
implementations could be updated to send over fully-featured target.xml
files.
In the future, it might be nice to address this alongside #143 or #12, but I think manually adding these XML defns here is totally reasonable for now.
Given that this might be a general problem (not specific to just RISC-V), we should avoid having #149 auto-close this issue. Can you update its description accordingly?
I'll go ahead and review that RISC-V PR, and we'll get it in to fix your use case :)
LLDB requires that the full list of registers is provided.
For example, for rv32, this string is currently returned:
This works fine with gdb (it seems to be ignore the register list), but llvm cares. To fix it, I changed it to this:
With that, lldb works out of the box; gdb is unaffected.
I think, lldb is actually within the spec to require this. See https://sourceware.org/gdb/current/onlinedocs/gdb.html/RISC_002dV-Features.html:
I'm working on a patch to address this.