Closed chenzhiy2001 closed 2 months ago
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 errorinterpreter-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.
Can you send your QEMU patches upstream for inclusion? Any ETA when your QEMU 8 Test is finished (I think for a plain first test the upstream version would work, no)?
Nonetheless a registerLimit
config option of type string - if set then added verbatim to that line
const result = await this.sendCommand("data-list-register-values N");
seems useful some people may only want a handful registers in any case) - could you try adding that and providing a PR for that?
Sorry for the long wait, I have time doing this just recently.
Can you send your QEMU patches upstream for inclusion?
The newest QEMU source code has changed a variable used in the patch (the variable was MachineState *mc
in the patch, but MachineState *ms
in the latest QEMU code) and I don't know if QEMU devs have changed anything other than the name itself, so I'm not sure whether the patch would work for the newest QEMU code even if I replace all mc
s with ms
s. The QEMU 8.0.5 code has the same problem.
So I gave up patching newer QEMU and uploaded the patch to Github gist for those who is curious about this patch.
Any ETA when your QEMU 8 Test is finished (I think for a plain first test the upstream version would work, no)?
The hobby OS I debugged don't boot on QEMU 8 so I use xv6-labs-2023
to test our issue instead.
When using my patched QEMU 7.0.0, The error is identical with my first post. Since my patch don't interfere with GDBStub, I think plain QEMU 7.0.0 will produce the same result.
When using plain QEMU 8.0.5, all registers including CSRs show up without any problem.
So my assumption is being proven: QEMU 7.0.0's gdbstub is problematic and QEMU 8.0.5 fixed it. It's not the VSCode Plugin's fault.
Nonetheless a registerLimit config option of type string - if set then added verbatim to that line seems useful, some people may only want a handful registers in any case) - could you try adding that and providing a PR for that?
Sure, see #444
gdb --version
>= 7.7.1gdb
cwd
andtarget
are properly setSometimes 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)