Skip to content

Commit 1e98030

Browse files
committed
Add automated GDB testing to server example
1 parent bbe1e42 commit 1e98030

3 files changed

Lines changed: 71 additions & 6 deletions

File tree

.github/workflows/cargo-build.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ jobs:
2020
- name: '🦀 Install Rust Toolchain'
2121
uses: dtolnay/rust-toolchain@stable
2222

23+
- name: '📦 Install Dependencies'
24+
run: |
25+
sudo apt-get update
26+
sudo apt-get install -y gdb-multiarch
27+
2328
- name: '🔨 Build'
2429
run: cargo build --verbose --examples
2530

examples/server.rs

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,79 @@
11
use unicorn_engine::unicorn_const::{Arch, Mode, Prot};
22
use unicorn_engine::{RegisterARM, Unicorn};
33

4+
const PORT: u16 = 1234;
5+
6+
const ARM_CODE32: &[u8] = &[
7+
0x0f, 0x00, 0xa0, 0xe1, 0x14, 0x00, 0x80, 0xe2, 0x00, 0x10, 0x90, 0xe5, 0x14, 0x10, 0x81, 0xe2, 0x00, 0x10, 0x80, 0xe5, 0xfb, 0xff, 0xff, 0xea,
8+
];
9+
10+
#[allow(dead_code)]
411
struct CustomData {
5-
pub _val: u32,
12+
test: [u8; 256],
13+
test2: String,
614
}
715

816
fn main() {
9-
let arm_code32: Vec<u8> = vec![
10-
0x0f, 0x00, 0xa0, 0xe1, 0x14, 0x00, 0x80, 0xe2, 0x00, 0x10, 0x90, 0xe5, 0x14, 0x10, 0x81, 0xe2, 0x00, 0x10, 0x80, 0xe5, 0xfb, 0xff, 0xff, 0xea,
11-
];
1217
let mut uc = Unicorn::new(Arch::ARM, Mode::LITTLE_ENDIAN).expect("Failed to initialize Unicorn instance");
1318
uc.mem_map(0x1000, 0x400, Prot::ALL).expect("Failed to map code page");
14-
uc.mem_write(0x1000, &arm_code32).expect("Failed to write instructions");
19+
uc.mem_write(0x1000, &ARM_CODE32).expect("Failed to write instructions");
1520
uc.reg_write(RegisterARM::PC as i32, 0x1000).expect("Failed write PC");
1621

17-
udbserver::udbserver(&mut uc, 1234, 0x1000).expect("Failed to start udbserver");
22+
udbserver::udbserver(&mut uc, PORT, 0x1000).expect("Failed to start udbserver");
23+
24+
uc.emu_start(0x1000, 0x2000, 0, 1000).expect("Failed to start emu");
25+
}
26+
27+
#[test]
28+
fn test_with_data() {
29+
use std::process::Command;
30+
use std::thread;
31+
32+
let data = CustomData {
33+
test: [0; 256],
34+
test2: String::from("ffffffffffffff"),
35+
};
36+
let mut uc = Unicorn::new_with_data(Arch::ARM, Mode::LITTLE_ENDIAN, data).expect("Failed to initialize Unicorn instance");
37+
uc.mem_map(0x1000, 0x400, Prot::ALL).expect("Failed to map code page");
38+
uc.mem_write(0x1000, &ARM_CODE32).expect("Failed to write instructions");
39+
uc.reg_write(RegisterARM::PC as i32, 0x1000).expect("Failed write PC");
40+
41+
udbserver::udbserver(&mut uc, PORT, 0x1000).expect("Failed to start udbserver");
42+
43+
thread::spawn(move || {
44+
let gdb_binary = if Command::new("gdb-multiarch").output().is_ok() {
45+
"gdb-multiarch"
46+
} else {
47+
"gdb"
48+
};
49+
50+
let output = Command::new(gdb_binary)
51+
.arg("-nx")
52+
.arg("-batch")
53+
.arg("-ex")
54+
.arg(format!("target remote localhost:{}", PORT))
55+
.arg("-ex")
56+
.arg("set architecture arm")
57+
.arg("-ex")
58+
.arg("break *0x1004")
59+
.arg("-ex")
60+
.arg("continue")
61+
.arg("-ex")
62+
.arg("stepi")
63+
.arg("-ex")
64+
.arg("quit")
65+
.output()
66+
.expect("Failed to execute GDB");
67+
68+
if output.status.success() {
69+
println!("GDB interaction success");
70+
println!("stdout:\n{}", String::from_utf8_lossy(&output.stdout));
71+
} else {
72+
eprintln!("GDB interaction failed with exit code: {:?}", output.status.code());
73+
eprintln!("stdout:\n{}", String::from_utf8_lossy(&output.stdout));
74+
eprintln!("stderr:\n{}", String::from_utf8_lossy(&output.stderr));
75+
}
76+
});
1877

1978
uc.emu_start(0x1000, 0x2000, 0, 1000).expect("Failed to start emu");
2079
}

shell.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
pkgs.mkShell {
44
buildInputs = with pkgs; [
55
git
6+
gdb
67
cmake
78
clang
89
cargo

0 commit comments

Comments
 (0)