Open Shai-Aviv opened 3 years ago
I’m generally leery of turning Spike into a Swiss Army knife. Certainly anything nearly as lengthy as the old gdbserver implementation doesn’t seem to be valuable enough to justify the maintenance burden.
Wouldn’t it be better to instead invest in improving and speeding up the OpeOCD approach?
I intend to implement gdbserver as similarly as possible to how the interactive debugger works, which should be simpler than the old gdbserver implementation.
The OpenOCD approach has other downsides apart from speed. For example, let's run this barel-metal program, which deliberately revokes access to all memory in all privilege modes:
0000000000001000 <_start>:
1000: 00000297 auipc t0,0x0
1004: 02428293 addi t0,t0,36 # 1024 <fail>
1008: 30529073 csrw mtvec,t0
100c: 0010029b addiw t0,zero,1
1010: 12da slli t0,t0,0x36
1012: 12fd addi t0,t0,-1
1014: 3b029073 csrw pmpaddr0,t0
1018: 08900293 li t0,137
101c: 3a029073 csrw pmpcfg0,t0
1020: 0001 nop
0000000000001022 <success>:
1022: a001 j 1022 <success>
0000000000001024 <fail>:
1024: a001 j 1024 <fail>
With the interactive debugger, it is possible to trace all instructions and traps, including the effect of mtvec
:
core 0: 0x0000000000001000 (0x00000297) auipc t0, 0x0
core 0: 0x0000000000001004 (0x02428293) addi t0, t0, 36
core 0: 0x0000000000001008 (0x30529073) csrw mtvec, t0
core 0: 0x000000000000100c (0x0010029b) addiw t0, zero, 1
core 0: 0x0000000000001010 (0x000012da) c.slli t0, 54
core 0: 0x0000000000001012 (0x000012fd) c.addi t0, -1
core 0: 0x0000000000001014 (0x3b029073) csrw pmpaddr0, t0
core 0: 0x0000000000001018 (0x08900293) li t0, 137
core 0: 0x000000000000101c (0x3a029073) csrw pmpcfg0, t0
core 0: exception trap_instruction_access_fault, epc 0x0000000000001020
core 0: tval 0x0000000000001020
core 0: exception trap_instruction_access_fault, epc 0x0000000000001024
core 0: tval 0x0000000000001024
We can also inspect the registers (reg 0
) to do a post-mortem without any problem.
On OpenOCD, the debug module needs to access the debug ROM, so the debugger is totally locked out:
=> 0x0000000000001000 <_start+0>: 97 02 00 00 auipc t0,0x0
=> 0x0000000000001004 <_start+4>: 93 82 42 02 addi t0,t0,36
=> 0x0000000000001008 <_start+8>: 73 90 52 30 csrw mtvec,t0
=> 0x000000000000100c <_start+12>: 9b 02 10 00 addiw t0,zero,1
=> 0x0000000000001010 <_start+16>: da 12 slli t0,t0,0x36
=> 0x0000000000001012 <_start+18>: fd 12 addi t0,t0,-1
=> 0x0000000000001014 <_start+20>: 73 90 02 3b csrw pmpaddr0,t0
=> 0x0000000000001018 <_start+24>: 93 02 90 08 li t0,137
=> 0x000000000000101c <_start+28>: 73 90 02 3a csrw pmpcfg0,t0
(gdb) stepi
unable to resume hart 0
dmstatus =0x00430c82
was stepping, halting
unable to halt hart 0
dmcontrol=0x80000001
dmstatus =0x00430c82
Hart was not halted after single step!
unable to step rtos hart
I think the advantages of a simulation-level debugger (such as the interactive debugger) are clear in this case.
I'm interested in making a pull request to bring back gdbserver support while keeping OpenOCD (
--rbb-port
) support intact. I find gdbserver valuable, since it enables faster memory accesses (especially for GDBdump
andrestore
commands), and can avoid clobberingmcycle
andminstret
, similarly to Spike's interactive debug (-d
) mode.While I have a go at it, I would like to gather your requirements for a "good" gdbserver implementation, that is, an implementation which you may consider merging.
Also see the commit message of a62a8196798141f3e76bc27da7671ab93951a677, which instills some hope in bringing back gdbserver support: