WebFreak001 / code-debug

Native debugging for VSCode

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Ignore unfetchable registers

chenzhiy2001 opened this issue · comments

  • If you are using gdb
    • gdb --version >= 7.7.1
    • it works on the command line with gdb
    • cwd and target are properly set

Sometimes a register is listed in GDB but its value is actually not fetchable even using command line gdb (I guess it's a bug of Qemu's GDBStub) . I think in this case, that specific register, rather than the whole register list, should be ignored.

In my case it's the "pmpcfg1" register that caused the issue.

The error message says: Could not expand variable: Could not fetch register "pmpcfg1"; remote failure reply 'E14' (from data-list-register-values N)

image

I think in this case, that specific register, rather than the whole register list, should be ignored.

I agree - but we currently get the value of all registers (which also provide us with the names) using data-list-register-values).
But looking at the docs there is an option --skip-unavailable.

Please recheck with plain GDB:
interpreter-exec mi2 "-data-list-register-values N" results in an error interpreter-exec mi2 "-data-list-register-values --skip-unavailable N" works.

If this is the case I can create a PR to include that.

Please recheck with plain GDB:
interpreter-exec mi2 "-data-list-register-values N" results in an error interpreter-exec mi2 "-data-list-register-values --skip-unavailable N" works.

They all result in the same error, how weird. Looks like GDB think that pmpcfg1 is avaliable, which is wrong because pmpcfg1 is specified as "RV32 only" in the RISC-V document (I am debugging an RV64 OS running in qemu-system-riscv64).

Could not fetch register "pmpcfg1"; remote failure reply 'E14' (from data-list-register-values N)
Could not fetch register "pmpcfg1"; remote failure reply 'E14' (from data-list-register-values --skip-unavailable N)

However, this works:

-data-list-register-values N 0 1 2 3 4 5 6 7 

GDB -> App: {
  "token": 86,
  "outOfBandRecord": "[]",
  "resultRecords": {
    "resultClass": "done",
    "results": "[["register-values",[[["number","0"],["value","0"]],[["number","1"],["value","0x8026bdb0 <os::rust_main+528>"]],[["number","2"],["value","0x8035ce70"]],[["number","3"],["value","0x0"]],[["number","4"],["value","0x0"]],[["number","5"],["value","4"]],[["number","6"],["value","2150024030"]],[["number","7"],["value","48"]]]]]"
  }
}

In short, --skip-unavailable won't work due to GDB or QEMU bugs. I thought of some workarounds like adding a "register whitelist" configuration in launch.json but that'll require a lot of extra work. Haven't thought of any simple and elegant solutions yet.

Currently I just changed the line in getRegisterValues() from

const result = await this.sendCommand("data-list-register-values N");

to:

const result = await this.sendCommand("data-list-register-values N 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32");

so at least I can see "regular" risc-v registers.

In short, --skip-unavailable won't work due to GDB or QEMU bugs.

Please double check for a recent GDB, if you have the error there as well report this to GDB buglist.

I thought of some workarounds like adding a "register whitelist" configuration in launch.json but that'll require a lot of extra work.

Hm, would this be more than a single configuration of type string registerLimit or similar? If set then this goes onto the request as-is, otherwise we don't set the limit.

Please double check for a recent GDB, if you have the error there as well report this to GDB buglist.

Upgraded GDB from v12.1 to the newest commit which is still v12.1 and the result is sadly the same. After some search I found that it’s actually QEMU’s fault, rather than GDB’s.

I’m using QEMU 7.0 and the changelog of QEMU 8.0 says they solved the problems related with CSRs including pmpcfg1:

Fixes to gdbstub, CSR accesses, dependencies between the various floating-point exceptions, and XTheadMemPair

I will test that newer version but that requires some time because my QEMU 7.0 has custom patches that enables extra serial ports. In order to let my guest OS running on QEMU 8.0 I have to do the same patch again.

Hm, would this be more than a single configuration of type string registerLimit or similar? If set then this goes onto the request as-is, otherwise we don't set the limit.

I think registerLimit will suffice in most situations since those special registers that caused the trouble are usually placed after the common registers.

If the user wants to watch a fetchable register exceeding registerLimit, he can use custom expressions.