daniel5151 / gdbstub

An ergonomic, featureful, and easy-to-integrate implementation of the GDB Remote Serial Protocol in Rust (with no-compromises #![no_std] support)
Other
291 stars 45 forks source link

SingleRegisterAccess: Support unavailable regs #107

Closed ptosi closed 2 years ago

ptosi commented 2 years ago

Description

Make gdbstub report to the GDB client the state of an unavailable (but valid) register by following the registers packet protocol:

[...] the stub may also return a string of literal xs in place of the register data digits, to indicate that the corresponding register has not been collected, thus its value is unavailable.

API Stability

Checklist

Validation

GDB output ``` (gdb) info registers SPSR_EL3 SPSR_EL3 ```
examples/armv4t ``` $ RUST_LOG=trace cargo run --example armv4t Compiling gdbstub v0.6.2 (/usr/local/google/home/ptosi/src/gdbstub) Finished dev [unoptimized + debuginfo] target(s) in 1.76s Running `target/debug/examples/armv4t` loading section ".text" into memory from [0x55550000..0x55550078] Setting PC to 0x55550000 Waiting for a GDB connection on "127.0.0.1:9001"... ``` then ``` (gdb) target remote localhost:9001 ``` makes the GDB client learn about the `Unavailable` register through the XML: ``` Debugger connected from 127.0.0.1:33718 TRACE gdbstub::protocol::recv_packet > <-- + TRACE gdbstub::protocol::recv_packet > <-- $qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;xmlRegisters=i386#6a TRACE gdbstub::protocol::response_writer > --> $PacketSize=1000;vContSupported+;multiprocess+;QStartNoAckMode+;ReverseContinue+;ReverseStep+;QDisableRandomization+;QEnvironmentHexEncoded+;QEnvironmentUnset+;QEnvironmentReset+;QStartupWithShell+;QSetWorkingDir+;swbreak+;hwbreak+;QCatchSyscalls+;qXfer:features:read+;qXfer:memory-map:read+;qXfer:exec-file:read+;qXfer:auxv:read+#fa [...] TRACE gdbstub::protocol::recv_packet > <-- $qXfer:features:read:extra.xml:0,ffb#16 TRACE gdbstub::protocol::response_writer > --> $m [...] #7d ``` Then requesting ``` (gdb) info registers unavailable ``` shows the appropriate request (`0x1c` = 28) and response (`xxxxxxxx` = 4 unknown bytes): ``` TRACE gdbstub::protocol::recv_packet > <-- $p1c#04 TRACE gdbstub::protocol::response_writer > --> $xxxxxxxx#c6 ``` which the GDB client reports: ``` (gdb) info registers unavailable unavailable ```
Before/After `./example_no_std/check_size.sh` output ### Before ``` File .text Size Crate Name 2.9% 72.7% 10.9KiB [Unknown] main 0.2% 4.6% 706B gdbstub gdbstub::stub::state_machine::GdbStubStateMachineInner::report_stop 0.1% 2.0% 310B gdbstub gdbstub::protocol::commands::breakpoint::BasicBreakpoint::from_slice 0.1% 1.7% 268B gdbstub gdbstub::protocol::common::hex::decode_hex_buf 0.1% 1.7% 259B gdbstub >::try_from 0.1% 1.6% 253B gdbstub gdbstub::protocol::response_writer::ResponseWriter::write_specific_thread_id 0.1% 1.6% 249B gdbstub gdbstub::stub::core_impl::resume::>::write_stop_common 0.1% 1.3% 207B gdbstub gdbstub::protocol::response_writer::ResponseWriter::write 0.0% 0.8% 130B gdbstub gdbstub::protocol::response_writer::ResponseWriter::inner_write 0.0% 0.8% 127B gdbstub gdbstub::protocol::common::hex::decode_hex 0.0% 0.7% 114B gdbstub gdbstub::protocol::common::hex::decode_hex 0.0% 0.7% 111B gdbstub gdbstub::protocol::response_writer::ResponseWriter::flush 0.0% 0.7% 104B gdbstub gdbstub::protocol::response_writer::ResponseWriter::write_num 0.0% 0.7% 103B gdbstub gdbstub::protocol::response_writer::ResponseWriter::write_num 0.0% 0.7% 102B gdbstub_nostd? ::read_addrs 0.0% 0.6% 96B gdbstub >::try_from 0.0% 0.6% 93B [Unknown] __libc_csu_init 0.0% 0.6% 88B gdbstub gdbstub::protocol::response_writer::ResponseWriter::write_hex 0.0% 0.5% 79B gdbstub ::from_be_bytes 0.0% 0.5% 77B gdbstub ::from_be_bytes 0.0% 0.4% 65B gdbstub_arch ::gdb_deserialize 0.0% 0.4% 65B gdbstub_nostd? ::write_addrs 0.0% 0.4% 65B gdbstub_nostd? ::write_registers 0.0% 0.4% 65B gdbstub_nostd? ::read_registers 0.0% 0.4% 57B compiler_builtins __rust_probestack 0.0% 0.3% 50B gdbstub_nostd? ::set_resume_action_continue 0.0% 0.3% 50B gdbstub_nostd? ::clear_resume_actions 0.0% 0.3% 50B gdbstub_nostd? ::resume 0.0% 0.3% 43B [Unknown] _start 0.0% 0.0% 6B gdbstub_nostd? ::remove_sw_breakpoint 0.0% 0.0% 6B gdbstub_nostd? ::add_sw_breakpoint 0.0% 0.0% 1B [Unknown] __libc_csu_fini 0.0% 0.0% 0B And 0 smaller methods. Use -n N to show more. 4.1% 100.0% 15.0KiB .text section size, the file size is 369.6KiB target/release/gdbstub-nostd : section size addr .interp 28 792 .note.gnu.property 32 824 .note.gnu.build-id 36 856 .note.ABI-tag 32 892 .gnu.hash 36 928 .dynsym 360 968 .dynstr 193 1328 .gnu.version 30 1522 .gnu.version_r 48 1552 .rela.dyn 408 1600 .init 23 4096 .plt 16 4128 .plt.got 8 4144 .text 15345 4160 .fini 9 19508 .rodata 914 20480 .eh_frame_hdr 284 21396 .eh_frame 1472 21680 .init_array 8 28072 .fini_array 8 28080 .dynamic 448 28088 .got 136 28536 .data 8 28672 .bss 8 28680 .comment 30 0 Total 19920 ``` ### After ``` File .text Size Crate Name 2.9% 72.7% 10.9KiB [Unknown] main 0.2% 4.6% 706B gdbstub gdbstub::stub::state_machine::GdbStubStateMachineInner::report_stop 0.1% 2.0% 310B gdbstub gdbstub::protocol::commands::breakpoint::BasicBreakpoint::from_slice 0.1% 1.7% 268B gdbstub gdbstub::protocol::common::hex::decode_hex_buf 0.1% 1.7% 259B gdbstub >::try_from 0.1% 1.6% 253B gdbstub gdbstub::protocol::response_writer::ResponseWriter::write_specific_thread_id 0.1% 1.6% 249B gdbstub gdbstub::stub::core_impl::resume::>::write_stop_common 0.1% 1.3% 207B gdbstub gdbstub::protocol::response_writer::ResponseWriter::write 0.0% 0.8% 130B gdbstub gdbstub::protocol::response_writer::ResponseWriter::inner_write 0.0% 0.8% 127B gdbstub gdbstub::protocol::common::hex::decode_hex 0.0% 0.7% 114B gdbstub gdbstub::protocol::common::hex::decode_hex 0.0% 0.7% 111B gdbstub gdbstub::protocol::response_writer::ResponseWriter::flush 0.0% 0.7% 104B gdbstub gdbstub::protocol::response_writer::ResponseWriter::write_num 0.0% 0.7% 103B gdbstub gdbstub::protocol::response_writer::ResponseWriter::write_num 0.0% 0.7% 102B gdbstub_nostd? ::read_addrs 0.0% 0.6% 96B gdbstub >::try_from 0.0% 0.6% 93B [Unknown] __libc_csu_init 0.0% 0.6% 88B gdbstub gdbstub::protocol::response_writer::ResponseWriter::write_hex 0.0% 0.5% 79B gdbstub ::from_be_bytes 0.0% 0.5% 77B gdbstub ::from_be_bytes 0.0% 0.4% 65B gdbstub_arch ::gdb_deserialize 0.0% 0.4% 65B gdbstub_nostd? ::write_addrs 0.0% 0.4% 65B gdbstub_nostd? ::write_registers 0.0% 0.4% 65B gdbstub_nostd? ::read_registers 0.0% 0.4% 57B compiler_builtins __rust_probestack 0.0% 0.3% 50B gdbstub_nostd? ::set_resume_action_continue 0.0% 0.3% 50B gdbstub_nostd? ::clear_resume_actions 0.0% 0.3% 50B gdbstub_nostd? ::resume 0.0% 0.3% 43B [Unknown] _start 0.0% 0.0% 6B gdbstub_nostd? ::remove_sw_breakpoint 0.0% 0.0% 6B gdbstub_nostd? ::add_sw_breakpoint 0.0% 0.0% 1B [Unknown] __libc_csu_fini 0.0% 0.0% 0B And 0 smaller methods. Use -n N to show more. 4.1% 100.0% 15.0KiB .text section size, the file size is 369.6KiB target/release/gdbstub-nostd : section size addr .interp 28 792 .note.gnu.property 32 824 .note.gnu.build-id 36 856 .note.ABI-tag 32 892 .gnu.hash 36 928 .dynsym 360 968 .dynstr 193 1328 .gnu.version 30 1522 .gnu.version_r 48 1552 .rela.dyn 408 1600 .init 23 4096 .plt 16 4128 .plt.got 8 4144 .text 15345 4160 .fini 9 19508 .rodata 914 20480 .eh_frame_hdr 284 21396 .eh_frame 1472 21680 .init_array 8 28072 .fini_array 8 28080 .dynamic 448 28088 .got 136 28536 .data 8 28672 .bss 8 28680 .comment 30 0 Total 19920 ```
ptosi commented 2 years ago

Sorry for forgetting about documentation, that's fixed. And thanks for explaining what's expected from the armv4t test, I've added support for an "Unavailable" register and updated this PR description with the GDB/test outputs.

Note that check_size.sh seems broken:

$ example_no_std/check_size.sh
   Compiling gdbstub v0.6.2 (/usr/local/google/home/ptosi/src/gdbstub)
    Finished release [optimized] target(s) in 3.21s
    Finished release [optimized] target(s) in 0.02s
Error: only 'bin', 'dylib' and 'cdylib' crate types are supported.

Should it be fixed?

daniel5151 commented 2 years ago

All good 👍

Ahh, yeah, check_size.sh assumes you're running it from inside the example_no_std directory. I should probably make that more clear.

ptosi commented 2 years ago

rustfmt should be happy, now!

ptosi commented 2 years ago

Output of example_no_std/check_size.sh added.