firedbg_rust_debugger/
event.rs

1use crate::{Bytes, Event, Reader};
2
3#[derive(Debug)]
4/// Event Stream
5pub struct EventStream {}
6
7#[cfg(feature = "debugger")]
8#[derive(Debug)]
9/// The current stack frame
10pub struct ActiveFrame {
11    pub frame_id: u64,
12    /// Aka SP
13    pub stack_pointer: u64,
14    /// Aka PC
15    pub program_counter: u64,
16    pub function_name: String,
17    pub function_id: lldb::SBFunctionId,
18}
19
20impl EventStream {
21    pub fn read_from(source: Bytes) -> Event {
22        let mut reader = Reader::new();
23        assert!(source.len() > 0);
24        let event = match source.get(0) {
25            b'B' => {
26                let reason = match source.get(1) {
27                    b'B' => crate::Reason::Breakpoint,
28                    b'P' => crate::Reason::Panic,
29                    other => panic!("Unknown reason, got {other:?}"),
30                };
31                reader.set_source(source, 2);
32                let breakpoint_id = reader.read_int().unwrap() as u32;
33                let thread_id = reader.read_int().unwrap();
34                let frame_id = reader.read_int().unwrap();
35                let locals = reader.read_values();
36                Event::Breakpoint {
37                    breakpoint_id,
38                    thread_id,
39                    frame_id,
40                    reason,
41                    locals,
42                }
43            }
44            b'F' => {
45                reader.set_source(source, 1);
46                let breakpoint_id = reader.read_int().unwrap() as u32;
47                let thread_id = reader.read_int().unwrap();
48                let frame_id = reader.read_int().unwrap();
49                let stack_pointer = reader.read_int().unwrap();
50                let function_name = reader.read_string().unwrap();
51                let arguments = reader.read_values();
52                Event::FunctionCall {
53                    breakpoint_id,
54                    thread_id,
55                    frame_id,
56                    stack_pointer,
57                    function_name,
58                    arguments,
59                }
60            }
61            b'R' => {
62                reader.set_source(source, 1);
63                let breakpoint_id = reader.read_int().unwrap() as u32;
64                let thread_id = reader.read_int().unwrap();
65                let frame_id = reader.read_int().unwrap();
66                let function_name = reader.read_string().unwrap();
67                let mut values = reader.read_values();
68                let (name, return_value) = values.remove(0);
69                assert_eq!(name, "return_value");
70                Event::FunctionReturn {
71                    breakpoint_id,
72                    thread_id,
73                    frame_id,
74                    function_name,
75                    return_value,
76                }
77            }
78            o => panic!("Unknown Event {o:?}"),
79        };
80        event
81    }
82}
83
84#[cfg(feature = "debugger")]
85impl EventStream {
86    pub fn breakpoint(
87        bp_id: crate::BpId,
88        thread_id: u64,
89        frame_id: u64,
90        reason: crate::Reason,
91    ) -> Bytes {
92        let mut bytes = Bytes::new();
93        bytes.push_byte(b'B');
94        bytes.push_byte(match reason {
95            crate::Reason::Breakpoint => b'B',
96            crate::Reason::Panic => b'P',
97        });
98        bytes.integer(bp_id.0);
99        bytes.integer(thread_id);
100        bytes.integer(frame_id);
101        bytes
102    }
103
104    pub fn function_call(bp_id: crate::BpId, thread_id: u64, active_frame: &ActiveFrame) -> Bytes {
105        let mut bytes = Bytes::new();
106        bytes.push_byte(b'F');
107        bytes.integer(bp_id.0);
108        bytes.integer(thread_id);
109        bytes.integer(active_frame.frame_id);
110        bytes.integer(active_frame.stack_pointer);
111        bytes.identifier(&active_frame.function_name);
112        bytes
113    }
114
115    pub fn function_return(
116        bp_id: crate::BpId,
117        thread_id: u64,
118        active_frame: &ActiveFrame,
119    ) -> Bytes {
120        let mut bytes = Bytes::new();
121        bytes.push_byte(b'R');
122        bytes.integer(bp_id.0);
123        bytes.integer(thread_id);
124        bytes.integer(active_frame.frame_id);
125        bytes.identifier(&active_frame.function_name);
126        bytes
127    }
128}