Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for QCatchSyscalls #57

Merged
merged 6 commits into from
May 28, 2021

Conversation

mchesser
Copy link
Contributor

@mchesser mchesser commented May 27, 2021

Description

Implements QCatchSyscalls extension, see: QCatchSyscalls.

I needed this for finding a bug in my emulator.

Notes:

There is a minor issue where if GDB sends syscall numbers larger than Arch::Usize, it will result in an integer overflow and the current implementation will silently ignore them and they will not reach the target. This is because I reused the argument handling code from vRun to avoid allocations. This could probably be improved by writing a new handler, but I avoided doing for now, since I wasn't sure about using the iterator approach to pass the syscall numbers to the Target impl any way.

API Stability

  • This PR does not require a breaking API change

Checklist

  • Implementation
    • cargo build compiles without errors or warnings
    • cargo clippy runs without errors or warnings
    • cargo fmt was run
    • All tests pass
  • Documentation
    • rustdoc + appropriate inline code comments
    • Updated CHANGELOG.md
    • (if appropriate) Added feature to "Debugging Features" in README.md
  • If implementing a new protocol extension IDET
    • Included a basic sample implementation in examples/armv4t
    • Included output of running examples/armv4t with RUST_LOG=trace + any relevant GDB output under the "Validation" section below
    • Confirmed that IDET can be optimized away (using ./scripts/test_dead_code_elim.sh and/or ./example_no_std/check_size.sh)

Validation

GDB output
(gdb) catch syscall read
Catchpoint 1 (syscall 'read' [3])
(gdb) si
0x55550004 in ?? ()
(gdb) catch syscall g:network
Catchpoint 2 (syscalls 'sendfile' [187] 'sendfile64' [239] 'socket' [281] 'bind' [282] 'connect' [283] 'listen' [284] 'accept' [285]
 'getsockname' [286] 'getpeername' [287] 'socketpair' [288] 'send' [289] 'sendto' [290] 'recv' [291] 'recvfrom' [292] 'shutdown' [29
3] 'setsockopt' [294] 'getsockopt' [295] 'sendmsg' [296] 'recvmsg' [297] 'recvmmsg' [365] 'accept4' [366] 'sendmmsg' [374])
(gdb) si
0x55550008 in ?? ()
(gdb) catch syscall
Catchpoint 3 (any syscall)
(gdb) si
0x5555000c in ?? ()
armv4t output
loading section ".text" into memory from [0x55550000..0x55550078]
Setting PC to 0x55550000
Waiting for a GDB connection on "127.0.0.1:9001"...
Debugger connected from 127.0.0.1:24166
 TRACE gdbstub::gdbstub_impl > <-- +
 TRACE gdbstub::gdbstub_impl > <-- $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+#cc
 TRACE gdbstub::gdbstub_impl              > <-- +
 TRACE gdbstub::gdbstub_impl              > <-- $vMustReplyEmpty#3a
 INFO  gdbstub::gdbstub_impl              > Unknown command: vMustReplyEmpty
 TRACE gdbstub::protocol::response_writer > --> $#00
 TRACE gdbstub::gdbstub_impl              > <-- +
 TRACE gdbstub::gdbstub_impl              > <-- $QStartNoAckMode#b0
 TRACE gdbstub::protocol::response_writer > --> $OK#9a
 TRACE gdbstub::gdbstub_impl              > <-- +
 TRACE gdbstub::gdbstub_impl              > <-- $Hgp0.0#ad
 TRACE gdbstub::protocol::response_writer > --> $OK#9a
 TRACE gdbstub::gdbstub_impl              > <-- $qXfer:features:read:target.xml:0,ffb#79
 TRACE gdbstub::protocol::response_writer > --> $l<target version="1.0"><!-- custom override string --><architecture>armv4t</architecture></target>#bb
 TRACE gdbstub::gdbstub_impl              > <-- $qTStatus#49
 INFO  gdbstub::gdbstub_impl              > Unknown command: qTStatus
 TRACE gdbstub::protocol::response_writer > --> $#00
 TRACE gdbstub::gdbstub_impl              > <-- $?#3f
 TRACE gdbstub::protocol::response_writer > --> $S05#b8
 TRACE gdbstub::gdbstub_impl              > <-- $qfThreadInfo#bb
 TRACE gdbstub::protocol::response_writer > --> $mp01.01#cd
 TRACE gdbstub::gdbstub_impl              > <-- $qsThreadInfo#c8
 TRACE gdbstub::protocol::response_writer > --> $l#6c
 TRACE gdbstub::gdbstub_impl              > <-- $qAttached:1#fa
GDB queried if it was attached to a process with PID 1
 TRACE gdbstub::protocol::response_writer > --> $1#31
 TRACE gdbstub::gdbstub_impl              > <-- $Hc-1#09
 TRACE gdbstub::protocol::response_writer > --> $OK#9a
 TRACE gdbstub::gdbstub_impl              > <-- $qC#b4
 INFO  gdbstub::gdbstub_impl              > Unknown command: qC
 TRACE gdbstub::protocol::response_writer > --> $#00
 TRACE gdbstub::gdbstub_impl              > <-- $g#67
 TRACE gdbstub::protocol::response_writer > --> $00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000107856341200005555xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx10000000#66
 TRACE gdbstub::gdbstub_impl              > <-- $qfThreadInfo#bb
 TRACE gdbstub::protocol::response_writer > --> $mp01.01#cd
 TRACE gdbstub::gdbstub_impl              > <-- $qsThreadInfo#c8
 TRACE gdbstub::protocol::response_writer > --> $l#6c
 TRACE gdbstub::gdbstub_impl              > <-- $qXfer:memory-map:read::0,ffb#18
 TRACE gdbstub::protocol::response_writer > --> $l<?xml version="1.0"?>
<!DOCTYPE memory-map
    PUBLIC "+//IDN gnu.org//DTD GDB Memory Map V1.0//EN"
            "http://sourceware.org/gdb/gdb-memory-map.dtd">
<memory-map>
    <memory type="ram" start="0x0" length="0x100000000"/>
</memory-map>#75
 TRACE gdbstub::gdbstub_impl              > <-- $m55550000,4#61
 TRACE gdbstub::protocol::response_writer > --> $04b02de5#26
 TRACE gdbstub::gdbstub_impl              > <-- $m5554fffc,4#35
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m55550000,4#61
 TRACE gdbstub::protocol::response_writer > --> $04b02de5#26
 TRACE gdbstub::gdbstub_impl              > <-- $m5554fffc,4#35
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m55550000,2#5f
 TRACE gdbstub::protocol::response_writer > --> $04b0#f6
 TRACE gdbstub::gdbstub_impl              > <-- $m5554fffe,2#35
 TRACE gdbstub::protocol::response_writer > --> $0000#7a
 TRACE gdbstub::gdbstub_impl              > <-- $m5554fffc,2#33
 TRACE gdbstub::protocol::response_writer > --> $0000#7a
 TRACE gdbstub::gdbstub_impl              > <-- $m55550000,2#5f
 TRACE gdbstub::protocol::response_writer > --> $04b0#f6
 TRACE gdbstub::gdbstub_impl              > <-- $m5554fffe,2#35
 TRACE gdbstub::protocol::response_writer > --> $0000#7a
 TRACE gdbstub::gdbstub_impl              > <-- $m5554fffc,2#33
 TRACE gdbstub::protocol::response_writer > --> $0000#7a
 TRACE gdbstub::gdbstub_impl              > <-- $m55550000,4#61
 TRACE gdbstub::protocol::response_writer > --> $04b02de5#26
 TRACE gdbstub::gdbstub_impl              > <-- $m5554fffc,4#35
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m55550000,4#61
 TRACE gdbstub::protocol::response_writer > --> $04b02de5#26
 TRACE gdbstub::gdbstub_impl              > <-- $m5554fffc,4#35
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m55550000,4#61
 TRACE gdbstub::protocol::response_writer > --> $04b02de5#26
 TRACE gdbstub::gdbstub_impl              > <-- $m55550000,4#61
 TRACE gdbstub::protocol::response_writer > --> $04b02de5#26
 TRACE gdbstub::gdbstub_impl              > <-- $m55550000,4#61
 TRACE gdbstub::protocol::response_writer > --> $04b02de5#26
 TRACE gdbstub::gdbstub_impl              > <-- $m0,4#fd
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $QCatchSyscalls:1;3#5b
Enabled catching syscalls: [3]
 TRACE gdbstub::protocol::response_writer > --> $OK#9a
 TRACE gdbstub::gdbstub_impl              > <-- $vCont?#49
 TRACE gdbstub::protocol::response_writer > --> $vCont;c;C;s;S;r#0f
 TRACE gdbstub::gdbstub_impl              > <-- $vCont;s:p1.1;c:p1.-1#f7
 TRACE armv4t_emu::arm                    > ARM: pc: 0x55550000, inst: 0xe52db004, cond: 0xe, cflags: 0000
 TRACE armv4t_emu::arm                    > Instruction: SingleXferI
 TRACE gdbstub::protocol::response_writer > --> $S05#b8
 TRACE gdbstub::gdbstub_impl              > <-- $g#67
 TRACE gdbstub::protocol::response_writer > --> $00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fcffff0f7856341204005555xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx10000000#87
 TRACE gdbstub::gdbstub_impl              > <-- $m55550004,4#65
 TRACE gdbstub::protocol::response_writer > --> $00b08de2#25
 TRACE gdbstub::gdbstub_impl              > <-- $m55550000,4#61
 TRACE gdbstub::protocol::response_writer > --> $04b02de5#26
 TRACE gdbstub::gdbstub_impl              > <-- $m55550004,4#65
 TRACE gdbstub::protocol::response_writer > --> $00b08de2#25
 TRACE gdbstub::gdbstub_impl              > <-- $m55550000,4#61
 TRACE gdbstub::protocol::response_writer > --> $04b02de5#26
 TRACE gdbstub::gdbstub_impl              > <-- $m55550004,2#63
 TRACE gdbstub::protocol::response_writer > --> $00b0#f2
 TRACE gdbstub::gdbstub_impl              > <-- $m55550002,2#61
 TRACE gdbstub::protocol::response_writer > --> $2de5#30
 TRACE gdbstub::gdbstub_impl              > <-- $m55550000,2#5f
 TRACE gdbstub::protocol::response_writer > --> $04b0#f6
 TRACE gdbstub::gdbstub_impl              > <-- $m55550004,2#63
 TRACE gdbstub::protocol::response_writer > --> $00b0#f2
 TRACE gdbstub::gdbstub_impl              > <-- $m55550002,2#61
 TRACE gdbstub::protocol::response_writer > --> $2de5#30
 TRACE gdbstub::gdbstub_impl              > <-- $m55550000,2#5f
 TRACE gdbstub::protocol::response_writer > --> $04b0#f6
 TRACE gdbstub::gdbstub_impl              > <-- $m55550004,4#65
 TRACE gdbstub::protocol::response_writer > --> $00b08de2#25
 TRACE gdbstub::gdbstub_impl              > <-- $m55550000,4#61
 TRACE gdbstub::protocol::response_writer > --> $04b02de5#26
 TRACE gdbstub::gdbstub_impl              > <-- $m55550004,4#65
 TRACE gdbstub::protocol::response_writer > --> $00b08de2#25
 TRACE gdbstub::gdbstub_impl              > <-- $m55550000,4#61
 TRACE gdbstub::protocol::response_writer > --> $04b02de5#26
 TRACE gdbstub::gdbstub_impl              > <-- $m55550004,4#65
 TRACE gdbstub::protocol::response_writer > --> $00b08de2#25
 TRACE gdbstub::gdbstub_impl              > <-- $m55550004,4#65
 TRACE gdbstub::protocol::response_writer > --> $00b08de2#25
 TRACE gdbstub::gdbstub_impl              > <-- $m55550004,4#65
 TRACE gdbstub::protocol::response_writer > --> $00b08de2#25
 TRACE gdbstub::gdbstub_impl              > <-- $m0,4#fd
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,4#71
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345674,4#6d
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,4#71
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345674,4#6d
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,2#6f
 TRACE gdbstub::protocol::response_writer > --> $0000#7a
 TRACE gdbstub::gdbstub_impl              > <-- $m12345676,2#6d
 TRACE gdbstub::protocol::response_writer > --> $0000#7a
 TRACE gdbstub::gdbstub_impl              > <-- $m12345674,2#6b
 TRACE gdbstub::protocol::response_writer > --> $0000#7a
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,2#6f
 TRACE gdbstub::protocol::response_writer > --> $0000#7a
 TRACE gdbstub::gdbstub_impl              > <-- $m12345676,2#6d
 TRACE gdbstub::protocol::response_writer > --> $0000#7a
 TRACE gdbstub::gdbstub_impl              > <-- $m12345674,2#6b
 TRACE gdbstub::protocol::response_writer > --> $0000#7a
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,4#71
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345674,4#6d
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,4#71
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345674,4#6d
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,4#71
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,4#71
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,4#71
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m0,4#fd
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $qfThreadInfo#bb
 TRACE gdbstub::protocol::response_writer > --> $mp01.01#cd
 TRACE gdbstub::gdbstub_impl              > <-- $qsThreadInfo#c8
 TRACE gdbstub::protocol::response_writer > --> $l#6c
 TRACE gdbstub::gdbstub_impl              > <-- $QCatchSyscalls:0#ec
Disabled catching syscalls
 TRACE gdbstub::protocol::response_writer > --> $OK#9a
 TRACE gdbstub::gdbstub_impl              > <-- $QCatchSyscalls:1;3#5b
Enabled catching syscalls: [3]
 TRACE gdbstub::protocol::response_writer > --> $OK#9a
 TRACE gdbstub::gdbstub_impl              > <-- $QCatchSyscalls:1;3;bb;ef;119;11a;11b;11c;11d;11e;11f;120;121;122;123;124;125;126;127;128;129;16d;16e;176#58
Enabled catching syscalls: [3, 187, 239, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 365, 366, 374]
 TRACE gdbstub::protocol::response_writer > --> $OK#9a
 TRACE gdbstub::gdbstub_impl              > <-- $vCont;s:p1.1;c:p1.-1#f7
 TRACE armv4t_emu::arm                    > ARM: pc: 0x55550004, inst: 0xe28db000, cond: 0xe, cflags: 0000
 TRACE armv4t_emu::arm                    > Instruction: DataProc2
 TRACE gdbstub::protocol::response_writer > --> $S05#b8
 TRACE gdbstub::gdbstub_impl              > <-- $g#67
 TRACE gdbstub::protocol::response_writer > --> $0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fcffff0f00000000fcffff0f7856341208005555xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx10000000#63
 TRACE gdbstub::gdbstub_impl              > <-- $m55550008,4#69
 TRACE gdbstub::protocol::response_writer > --> $14d04de2#28
 TRACE gdbstub::gdbstub_impl              > <-- $m55550004,4#65
 TRACE gdbstub::protocol::response_writer > --> $00b08de2#25
 TRACE gdbstub::gdbstub_impl              > <-- $m55550008,4#69
 TRACE gdbstub::protocol::response_writer > --> $14d04de2#28
 TRACE gdbstub::gdbstub_impl              > <-- $m55550004,4#65
 TRACE gdbstub::protocol::response_writer > --> $00b08de2#25
 TRACE gdbstub::gdbstub_impl              > <-- $m55550008,2#67
 TRACE gdbstub::protocol::response_writer > --> $14d0#f9
 TRACE gdbstub::gdbstub_impl              > <-- $m55550006,2#65
 TRACE gdbstub::protocol::response_writer > --> $8de2#33
 TRACE gdbstub::gdbstub_impl              > <-- $m55550004,2#63
 TRACE gdbstub::protocol::response_writer > --> $00b0#f2
 TRACE gdbstub::gdbstub_impl              > <-- $m55550008,2#67
 TRACE gdbstub::protocol::response_writer > --> $14d0#f9
 TRACE gdbstub::gdbstub_impl              > <-- $m55550006,2#65
 TRACE gdbstub::protocol::response_writer > --> $8de2#33
 TRACE gdbstub::gdbstub_impl              > <-- $m55550004,2#63
 TRACE gdbstub::protocol::response_writer > --> $00b0#f2
 TRACE gdbstub::gdbstub_impl              > <-- $m55550008,4#69
 TRACE gdbstub::protocol::response_writer > --> $14d04de2#28
 TRACE gdbstub::gdbstub_impl              > <-- $m55550004,4#65
 TRACE gdbstub::protocol::response_writer > --> $00b08de2#25
 TRACE gdbstub::gdbstub_impl              > <-- $m55550008,4#69
 TRACE gdbstub::protocol::response_writer > --> $14d04de2#28
 TRACE gdbstub::gdbstub_impl              > <-- $m55550004,4#65
 TRACE gdbstub::protocol::response_writer > --> $00b08de2#25
 TRACE gdbstub::gdbstub_impl              > <-- $m55550008,4#69
 TRACE gdbstub::protocol::response_writer > --> $14d04de2#28
 TRACE gdbstub::gdbstub_impl              > <-- $m55550008,4#69
 TRACE gdbstub::protocol::response_writer > --> $14d04de2#28
 TRACE gdbstub::gdbstub_impl              > <-- $m55550008,4#69
 TRACE gdbstub::protocol::response_writer > --> $14d04de2#28
 TRACE gdbstub::gdbstub_impl              > <-- $mffffffc,4#94
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,4#71
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345674,4#6d
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,4#71
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345674,4#6d
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,2#6f
 TRACE gdbstub::protocol::response_writer > --> $0000#7a
 TRACE gdbstub::gdbstub_impl              > <-- $m12345676,2#6d
 TRACE gdbstub::protocol::response_writer > --> $0000#7a
 TRACE gdbstub::gdbstub_impl              > <-- $m12345674,2#6b
 TRACE gdbstub::protocol::response_writer > --> $0000#7a
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,2#6f
 TRACE gdbstub::protocol::response_writer > --> $0000#7a
 TRACE gdbstub::gdbstub_impl              > <-- $m12345676,2#6d
 TRACE gdbstub::protocol::response_writer > --> $0000#7a
 TRACE gdbstub::gdbstub_impl              > <-- $m12345674,2#6b
 TRACE gdbstub::protocol::response_writer > --> $0000#7a
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,4#71
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345674,4#6d
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,4#71
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345674,4#6d
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,4#71
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,4#71
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,4#71
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $mffffffc,4#94
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $qfThreadInfo#bb
 TRACE gdbstub::protocol::response_writer > --> $mp01.01#cd
 TRACE gdbstub::gdbstub_impl              > <-- $qsThreadInfo#c8
 TRACE gdbstub::protocol::response_writer > --> $l#6c
 TRACE gdbstub::gdbstub_impl              > <-- $QCatchSyscalls:1;bb;ef;119;11a;11b;11c;11d;11e;11f;120;121;122;123;124;125;126;127;128;129;16d;16e;176#ea
Enabled catching syscalls: [187, 239, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 365, 366, 374]
 TRACE gdbstub::protocol::response_writer > --> $OK#9a
 TRACE gdbstub::gdbstub_impl              > <-- $QCatchSyscalls:0#ec
Disabled catching syscalls
 TRACE gdbstub::protocol::response_writer > --> $OK#9a
 TRACE gdbstub::gdbstub_impl              > <-- $QCatchSyscalls:1;3#5b
Enabled catching syscalls: [3]
 TRACE gdbstub::protocol::response_writer > --> $OK#9a
 TRACE gdbstub::gdbstub_impl              > <-- $QCatchSyscalls:1;3;bb;ef;119;11a;11b;11c;11d;11e;11f;120;121;122;123;124;125;126;127;128;129;16d;16e;176#58
Enabled catching syscalls: [3, 187, 239, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 365, 366, 374]
 TRACE gdbstub::protocol::response_writer > --> $OK#9a
 TRACE gdbstub::gdbstub_impl              > <-- $QCatchSyscalls:1#ed
Enabled catching all syscalls
 TRACE gdbstub::protocol::response_writer > --> $OK#9a
 TRACE gdbstub::gdbstub_impl              > <-- $vCont;s:p1.1;c:p1.-1#f7
 TRACE armv4t_emu::arm                    > ARM: pc: 0x55550008, inst: 0xe24dd014, cond: 0xe, cflags: 0000
 TRACE armv4t_emu::arm                    > Instruction: DataProc2
 TRACE gdbstub::protocol::response_writer > --> $S05#b8
 TRACE gdbstub::gdbstub_impl              > <-- $g#67
 TRACE gdbstub::protocol::response_writer > --> $0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fcffff0f00000000e8ffff0f785634120c005555xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx10000000#62
 TRACE gdbstub::gdbstub_impl              > <-- $m5555000c,4#94
 TRACE gdbstub::protocol::response_writer > --> $0430a0e3#f0
 TRACE gdbstub::gdbstub_impl              > <-- $m55550008,4#69
 TRACE gdbstub::protocol::response_writer > --> $14d04de2#28
 TRACE gdbstub::gdbstub_impl              > <-- $m5555000c,4#94
 TRACE gdbstub::protocol::response_writer > --> $0430a0e3#f0
 TRACE gdbstub::gdbstub_impl              > <-- $m55550008,4#69
 TRACE gdbstub::protocol::response_writer > --> $14d04de2#28
 TRACE gdbstub::gdbstub_impl              > <-- $m5555000c,2#92
 TRACE gdbstub::protocol::response_writer > --> $0430#c7
 TRACE gdbstub::gdbstub_impl              > <-- $m5555000a,2#90
 TRACE gdbstub::protocol::response_writer > --> $4de2#2f
 TRACE gdbstub::gdbstub_impl              > <-- $m55550008,2#67
 TRACE gdbstub::protocol::response_writer > --> $14d0#f9
 TRACE gdbstub::gdbstub_impl              > <-- $m5555000c,2#92
 TRACE gdbstub::protocol::response_writer > --> $0430#c7
 TRACE gdbstub::gdbstub_impl              > <-- $m5555000a,2#90
 TRACE gdbstub::protocol::response_writer > --> $4de2#2f
 TRACE gdbstub::gdbstub_impl              > <-- $m55550008,2#67
 TRACE gdbstub::protocol::response_writer > --> $14d0#f9
 TRACE gdbstub::gdbstub_impl              > <-- $m5555000c,4#94
 TRACE gdbstub::protocol::response_writer > --> $0430a0e3#f0
 TRACE gdbstub::gdbstub_impl              > <-- $m55550008,4#69
 TRACE gdbstub::protocol::response_writer > --> $14d04de2#28
 TRACE gdbstub::gdbstub_impl              > <-- $m5555000c,4#94
 TRACE gdbstub::protocol::response_writer > --> $0430a0e3#f0
 TRACE gdbstub::gdbstub_impl              > <-- $m55550008,4#69
 TRACE gdbstub::protocol::response_writer > --> $14d04de2#28
 TRACE gdbstub::gdbstub_impl              > <-- $m5555000c,4#94
 TRACE gdbstub::protocol::response_writer > --> $0430a0e3#f0
 TRACE gdbstub::gdbstub_impl              > <-- $m5555000c,4#94
 TRACE gdbstub::protocol::response_writer > --> $0430a0e3#f0
 TRACE gdbstub::gdbstub_impl              > <-- $m5555000c,4#94
 TRACE gdbstub::protocol::response_writer > --> $0430a0e3#f0
 TRACE gdbstub::gdbstub_impl              > <-- $mffffffc,4#94
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,4#71
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345674,4#6d
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,4#71
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345674,4#6d
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,2#6f
 TRACE gdbstub::protocol::response_writer > --> $0000#7a
 TRACE gdbstub::gdbstub_impl              > <-- $m12345676,2#6d
 TRACE gdbstub::protocol::response_writer > --> $0000#7a
 TRACE gdbstub::gdbstub_impl              > <-- $m12345674,2#6b
 TRACE gdbstub::protocol::response_writer > --> $0000#7a
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,2#6f
 TRACE gdbstub::protocol::response_writer > --> $0000#7a
 TRACE gdbstub::gdbstub_impl              > <-- $m12345676,2#6d
 TRACE gdbstub::protocol::response_writer > --> $0000#7a
 TRACE gdbstub::gdbstub_impl              > <-- $m12345674,2#6b
 TRACE gdbstub::protocol::response_writer > --> $0000#7a
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,4#71
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345674,4#6d
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,4#71
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345674,4#6d
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,4#71
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,4#71
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $m12345678,4#71
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $mffffffc,4#94
 TRACE gdbstub::protocol::response_writer > --> $00000000#7e
 TRACE gdbstub::gdbstub_impl              > <-- $qfThreadInfo#bb
 TRACE gdbstub::protocol::response_writer > --> $mp01.01#cd
 TRACE gdbstub::gdbstub_impl              > <-- $qsThreadInfo#c8
 TRACE gdbstub::protocol::response_writer > --> $l#6c
 TRACE gdbstub::gdbstub_impl              > <-- $QCatchSyscalls:1#ed
Enabled catching all syscalls
 TRACE gdbstub::protocol::response_writer > --> $OK#9a
 TRACE gdbstub::gdbstub_impl              > <-- $QCatchSyscalls:1#ed
Enabled catching all syscalls
 TRACE gdbstub::protocol::response_writer > --> $OK#9a
 TRACE gdbstub::gdbstub_impl              > <-- $QCatchSyscalls:0#ec
Disabled catching syscalls
 TRACE gdbstub::protocol::response_writer > --> $OK#9a

Since the example implementation never actually performs a syscall, I've also attached a trace of it running in my emulator (binary just prints Hello World using a single writev syscall).

GDB output
(gdb) file ./bin/hello-world
Reading symbols from ./bin/hello-world...
(gdb) catch syscall writev
Catchpoint 1 (syscall 'writev' [20])
(gdb) target remote :9999
Remote debugging using :9999
0x000000000040014d in _start ()
(gdb) continue
Continuing.

Catchpoint 1 (call to syscall writev), 0x00000000004010c6 in __stdio_write ()
(gdb)
Continuing.

Catchpoint 1 (returned from syscall writev), 0x00000000004010c6 in __stdio_write ()
(gdb)
Continuing.
[Inferior 1 (process 1) exited normally]
Protocol output
w +$qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;xmlRegisters=i386#6a
r +$PacketSize=1000;vContSupported+;multiprocess+;QStartNoAckMode+;ReverseStep+;swbreak+;QCatchSyscalls+;qXfer:features:read+#c3
w +$vMustReplyEmpty#3a
r +$#00
w +$QStartNoAckMode#b0
r +$OK#9a
w +$Hgp0.0#ad
r $OK#9a
w $qXfer:features:read:target.xml:0,ffb#79
r $l<target version="1.0"><architecture>i386:x86-64</architecture><feature name="org.gnu.gdb.i386.sse"></feature></target>#c6
w $qTStatus#49
r $#00
w $?#3f
r $S05#b8
w $qfThreadInfo#bb
r $mp01.01#cd
w $qsThreadInfo#c8
r $l#6c
w $qAttached:1#fa
r $1#31
w $Hc-1#09
r $OK#9a
w $qC#b4
r $#00
w $qOffsets#4b
r $TextSeg=40*!#b0
w $g#67
r $0*~0**b0fe0f010*~0*B4d0140*(20*~0*~0*~0*~0*~0*~0*~0*~0**x*L#37
w $qfThreadInfo#bb
r $mp01.01#cd
w $qsThreadInfo#c8
r $l#6c
w $m40014d,1#27
r $48#6c
w $m40014d,1#27
r $48#6c
w $qSymbol::#5b
r $#00
c continue
w $QCatchSyscalls:1;14#8d
r $OK#9a
w $vCont?#49
r $vCont;c;C;s;S#62
w $vCont;c:p1.-1#0f
r <Timeout: 0 seconds>$T05syscall_entry:14;#1f
w $g#67
r $140**402060*'c81040*(20**80fd0f010*%10*+20**70fd0f010*%b0**17fe0f010*%10*;20**140*+c0**80fd0f010*$c61040*(20*~0*~0*~0*~0*~0*~0*~0*~0**x*L#20
w $qfThreadInfo#bb
r $mp01.01#cd
w $qsThreadInfo#c8
r $l#6c
w $QCatchSyscalls:0#ec
r $OK#9a
w $m4010c6,1#28
r $0f#96
w $m4010c6,1#28
r $0f#96
c continue
w $QCatchSyscalls:1;14#8d
r $OK#9a
w $vCont;c:p1.-1#0f
r <Timeout: 0 seconds>$T05syscall_return:14;#8d
w $g#67
r $0c0**402060*'c81040*(20**80fd0f010*%10*+20**70fd0f010*%b0**17fe0f010*%10*;20**140*+c0**80fd0f010*$c61040*(20*~0*~0*~0*~0*~0*~0*~0*~0**x*L#4e
w $qfThreadInfo#bb
r $mp01.01#cd
w $qsThreadInfo#c8
r $l#6c
w $QCatchSyscalls:0#ec
r $OK#9a
w $m4010c6,1#28
r $0f#96
w $m4010c6,1#28
r $0f#96
c continue
w $QCatchSyscalls:1;14#8d
r $OK#9a
w $vCont;c:p1.-1#0f
r <Timeout: 0 seconds>$W00#b7
End of log

@daniel5151 daniel5151 self-requested a review May 27, 2021 15:37
Copy link
Owner

@daniel5151 daniel5151 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for yet another great PR!

As always, the core implementation looks great, and my comments are primarily nits.

I think the iterator approach is a fine way to pass syscall numbers to the Target. The alternative would be to break the API into multiple methods such as as catch_syscall(&mut self, syscall_no: Usize) and clear_filter(&mut self, syscall_no: Usize), where you iterate over the list within gdbstub and invoke catch_syscall for each syscall. I'll leave it up to you to decide how you'd like the API to work, since you've got hands on experience actually implementing the underlying Target functionality.

And thank you for taking the initiative to include the protocol output from your emulator! I'll update the PR template to include something along the lines of "if the feature isn't feasible to demo in armv4t, please include output from your own gdbstub integration".

src/gdbstub_impl/ext/catch_syscalls.rs Outdated Show resolved Hide resolved
src/target/mod.rs Outdated Show resolved Hide resolved
src/protocol/common/hex.rs Outdated Show resolved Hide resolved
src/protocol/commands.rs Outdated Show resolved Hide resolved
src/protocol/common/hex.rs Outdated Show resolved Hide resolved
src/target/ext/catch_syscalls.rs Outdated Show resolved Hide resolved
src/target/ext/catch_syscalls.rs Outdated Show resolved Hide resolved
@mchesser
Copy link
Contributor Author

Updated with changes and rebased on top of the latest master.

Copy link
Owner

@daniel5151 daniel5151 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've got one final nit, but aside from that, LGTM!

Just a heads up, but I'll be out from the 28th (tomorrow) to the 31st (monday). As such, while we could probably merge this into master tonight, I don't think I'll have time to cut a 0.5.1 release until early next week.

src/target/ext/catch_syscalls.rs Outdated Show resolved Hide resolved
@mchesser
Copy link
Contributor Author

Great, thanks.

It's not an issue for me not being released -- I have many patched github dependencies already.

Copy link
Owner

@daniel5151 daniel5151 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good 👍

I also realized that there were a couple minor things I missed that'll need to get fixed - sorry 😅
Once those are ironed out, we should be good to go.

examples/armv4t/gdb/catch_syscalls.rs Show resolved Hide resolved
src/target/ext/catch_syscalls.rs Show resolved Hide resolved
@mchesser
Copy link
Contributor Author

Done. I've also updated the trace output in the PR description.

@daniel5151 daniel5151 self-requested a review May 28, 2021 15:35
@daniel5151 daniel5151 merged commit a33bbae into daniel5151:master May 28, 2021
@daniel5151
Copy link
Owner

Awesome. Thanks again! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants