Casting C memory to rust data structure in a core using rust-gdb

Hi,
I need to debug a core of Suricata process, which mixes C and rust. I need to walk the data structures in the core using a gdb script. Below is backtrace from a running program to illustrate what I am trying to achieve.

(gdb) bt
#0  suricata::smb::smb::SMBState::free_tx (self=0x7fffe44faec0, tx_id=0) at src/smb/smb.rs:1999
#1  suricata::smb::smb::rs_smb_state_tx_free (state=0x7fffe44faec0, tx_id=0) at src/smb/smb.rs:1999
#2  0x00005555555cbee2 in AppLayerParserTransactionsCleanup (f=0x55555699bb10) at app-layer-parser.c:992
#3  0x000055555569451b in FlowWorker (tv=0x555558645e60, p=0x7fffec26c170, data=0x7fffec2b9020, preq=0x555558b81f00,
    unused=<optimized out>) at flow-worker.c:294
#4  0x000055555571aeab in TmThreadsSlotVarRun (tv=tv@entry=0x555558645e60, p=p@entry=0x7fffec26c170,
    slot=slot@entry=0x555558603780) at tm-threads.c:149
#5  0x00005555556f302e in TmThreadsSlotProcessPkt (p=0x7fffec26c170, s=0x555558603780, tv=0x555558645e60) at tm-threads.h:148
#6  AFPParsePacketV3 (pbd=0x7ffff0206000, ppd=0x7ffff0206340, ptv=<optimized out>) at source-af-packet.c:1124
#7  AFPWalkBlock (pbd=0x7ffff0206000, ptv=<optimized out>) at source-af-packet.c:1140
#8  AFPReadFromRingV3 (ptv=<optimized out>) at source-af-packet.c:1190
#9  0x00005555556f738e in ReceiveAFPLoop (tv=0x555558645e60, data=<optimized out>, slot=<optimized out>)
    at source-af-packet.c:1583
#10 0x000055555571f051 in TmThreadsSlotPktAcqLoop (td=0x555558645e60) at tm-threads.c:375
#11 0x00007ffff67586db in start_thread (arg=0x7ffff1cd8700) at pthread_create.c:463
#12 0x00007ffff4ac771f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
(gdb) frame 1
#1  suricata::smb::smb::rs_smb_state_tx_free (state=0x7fffe44faec0, tx_id=0) at src/smb/smb.rs:1999
1999        state.free_tx(tx_id);
(gdb) p state
$19 = (suricata::smb::smb::SMBState *) 0x7fffe44faec0
(gdb) p state.transactions.len
$20 = 4
(gdb) frame 2
#2  0x00005555555cbee2 in AppLayerParserTransactionsCleanup (f=0x55555699bb10) at app-layer-parser.c:992
992             p->StateTransactionFree(alstate, i);
(gdb) p (suricata::smb::smb::SMBState *) 0x7fffe44faec0
No type "smb" within class or namespace "suricata".
(gdb) p (0x7fffe44faec0 as *mut SMBState)
A syntax error in expression, near `as *mut SMBState)'.
(gdb) frame 1
#1  suricata::smb::smb::rs_smb_state_tx_free (state=0x7fffe44faec0, tx_id=0) at src/smb/smb.rs:1999
1999        state.free_tx(tx_id);
(gdb) p (0x7fffe44faec0 as *mut SMBState)
$21 = (suricata::smb::smb::SMBState *) 0x7fffe44faec0
(gdb) p (0x7fffe44faec0 as *mut SMBState).transactions.len
$22 = 4
(gdb)

In frame 1, the type of "state" is correctly known as it's rust code. In frame 2, if I want to cast the memory at address 0x7fffe44faec0 to SMBState, so that I can walk the datastructures, how would I do it? The following does not work in frame 2 (but works in frame 1)

gdb) p (0x7fffe44faec0 as *mut SMBState)
A syntax error in expression, near `as *mut SMBState)'.

Thanks in advance for any help.

Reference:

I was able to use "set language rust" to force GDB to decode the memory as a rust object. Hope this helps others

(gdb) set language rust
Warning: the current language does not match this frame.
(gdb) p (0x7fffe44faec0 as *mut suricata::smb::smb::SMBState).transactions.len
$31 = 4
(gdb) p (0x7fffe44faec0 as *mut suricata::smb::smb::SMBState).transactions
$32 = alloc::vec::Vecsuricata::smb::smb::SMBTransaction {buf: alloc::raw_vec::RawVec<suricata::smb::smb::SMBTransaction, alloc::alloc::Global> {ptr: core::ptr::unique::Uniquesuricata::smb::smb::SMBTransaction {pointer: 0x7fffe44fb3a0, _marker: core::marker::PhantomDatasuricata::smb::smb::SMBTransaction}, cap: 4, alloc: alloc::alloc::Global}, len: 4}
(gdb)

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.