riscv-software-src / riscv-isa-sim

Spike, a RISC-V ISA Simulator
Other
2.43k stars 855 forks source link

Bring back gdbserver support #708

Open Shai-Aviv opened 3 years ago

Shai-Aviv commented 3 years ago

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 GDB dump and restore commands), and can avoid clobbering mcycle and minstret, 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:

Remove gdbserver support.

Maybe some day we can bring it back, implementing direct access into registers and memory so it would be fast. That would be the way to usefully debug code running in spike, as opposed to the way that mirrors the actual debug design as it might be implemented in hardware.

aswaterman commented 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?

Shai-Aviv commented 3 years ago

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.