gdbstub_debugger/
gdbstub_debugger.rs1#[macro_use]
2extern crate log;
3
4use bytes::Bytes;
5use ckb_vm::{
6 DefaultCoreMachine, DefaultMachineBuilder, ISA_B, ISA_IMC, ISA_MOP, SparseMemory, SupportMachine, WXorXMemory,
7};
8#[cfg(feature = "stdio")]
9use ckb_vm_debug_utils::Stdio;
10use ckb_vm_debug_utils::{GdbStubHandler, GdbStubHandlerEventLoop};
11use gdbstub::{conn::ConnectionExt, stub::GdbStub};
12use gdbstub_arch::riscv::Riscv64;
13use std::env;
14use std::fs::File;
15use std::io::Read;
16use std::net::TcpListener;
17
18fn main() {
19 let _ = env_logger::init();
20 let args: Vec<String> = env::args().skip(1).collect();
21
22 let listener = TcpListener::bind(&args[0]).expect("listen");
23 debug!("Listening on {}", args[0]);
24
25 let mut file = File::open(&args[1]).expect("open program");
26 let mut buffer = Vec::new();
27 file.read_to_end(&mut buffer).unwrap();
28 let program: Bytes = buffer.into();
29 let program_args: Vec<Bytes> = args.into_iter().skip(1).map(|a| a.into()).collect();
30
31 for res in listener.incoming() {
32 debug!("Got connection");
33 if let Ok(stream) = res {
34 let machine_core = DefaultCoreMachine::<u64, WXorXMemory<SparseMemory<u64>>>::new(
36 ISA_IMC | ISA_B | ISA_MOP,
37 1,
38 u64::max_value(),
39 );
40 let machine_builder = DefaultMachineBuilder::new(machine_core);
41 #[cfg(feature = "stdio")]
42 let mut machine = machine_builder.syscall(Box::new(Stdio::new(true))).build();
43 #[cfg(not(feature = "stdio"))]
44 let mut machine = machine_builder.build();
45 machine.load_program(&program, program_args.iter().cloned().map(Ok)).expect("load program");
46 machine.set_running(true);
47 let mut h: GdbStubHandler<_, Riscv64> = GdbStubHandler::new(machine);
48 let connection: Box<(dyn ConnectionExt<Error = std::io::Error> + 'static)> = Box::new(stream);
49 let gdb = GdbStub::new(connection);
50
51 let result = gdb.run_blocking::<GdbStubHandlerEventLoop<_, _>>(&mut h);
52 println!("Disconnect reason: {:?}", result);
53 }
54 debug!("Connection closed");
55 }
56}