mielin_cells/debug/
mod.rs

1//! Debugging tools for MielinOS agents
2//!
3//! This module provides comprehensive debugging capabilities including:
4//! - State inspection API
5//! - Execution tracing
6//! - Memory profiling
7//! - Remote debugging
8
9pub mod inspector;
10pub mod profiler;
11pub mod remote;
12pub mod tracer;
13
14pub use inspector::{InspectionQuery, InspectionResult, StateInspector};
15pub use profiler::{AllocationRecord, MemoryProfiler, MemorySnapshot, ProfilingReport};
16pub use remote::{DebugCommand, DebugSession, DebuggerConfig, RemoteDebugger};
17pub use tracer::{ExecutionTracer, TraceEvent, TraceFilter, TraceRecorder};
18
19use serde::{Deserialize, Serialize};
20
21/// Debug context for an agent
22#[derive(Debug, Clone, Serialize, Deserialize)]
23pub struct DebugContext {
24    /// Agent ID being debugged
25    pub agent_id: [u8; 16],
26    /// Debug session ID
27    pub session_id: [u8; 16],
28    /// Debug mode enabled
29    pub enabled: bool,
30    /// Breakpoints
31    pub breakpoints: Vec<Breakpoint>,
32    /// Watch expressions
33    pub watches: Vec<WatchExpression>,
34}
35
36/// Breakpoint in agent execution
37#[derive(Debug, Clone, Serialize, Deserialize)]
38pub struct Breakpoint {
39    /// Breakpoint ID
40    pub id: u64,
41    /// Location (e.g., function name, line number)
42    pub location: String,
43    /// Condition (optional)
44    pub condition: Option<String>,
45    /// Hit count
46    pub hit_count: u64,
47    /// Enabled
48    pub enabled: bool,
49}
50
51/// Watch expression for monitoring values
52#[derive(Debug, Clone, Serialize, Deserialize)]
53pub struct WatchExpression {
54    /// Watch ID
55    pub id: u64,
56    /// Expression to evaluate
57    pub expression: String,
58    /// Last evaluated value
59    pub last_value: Option<String>,
60}
61
62impl DebugContext {
63    /// Create a new debug context
64    pub fn new(agent_id: [u8; 16]) -> Self {
65        use rand::Rng;
66        let mut rng = rand::rng();
67        let mut session_id = [0u8; 16];
68        rng.fill(&mut session_id);
69
70        Self {
71            agent_id,
72            session_id,
73            enabled: false,
74            breakpoints: Vec::new(),
75            watches: Vec::new(),
76        }
77    }
78
79    /// Enable debugging
80    pub fn enable(&mut self) {
81        self.enabled = true;
82    }
83
84    /// Disable debugging
85    pub fn disable(&mut self) {
86        self.enabled = false;
87    }
88
89    /// Add a breakpoint
90    pub fn add_breakpoint(&mut self, location: String, condition: Option<String>) -> u64 {
91        let id = self.breakpoints.len() as u64;
92        self.breakpoints.push(Breakpoint {
93            id,
94            location,
95            condition,
96            hit_count: 0,
97            enabled: true,
98        });
99        id
100    }
101
102    /// Remove a breakpoint
103    pub fn remove_breakpoint(&mut self, id: u64) -> bool {
104        if let Some(pos) = self.breakpoints.iter().position(|b| b.id == id) {
105            self.breakpoints.remove(pos);
106            true
107        } else {
108            false
109        }
110    }
111
112    /// Add a watch expression
113    pub fn add_watch(&mut self, expression: String) -> u64 {
114        let id = self.watches.len() as u64;
115        self.watches.push(WatchExpression {
116            id,
117            expression,
118            last_value: None,
119        });
120        id
121    }
122
123    /// Remove a watch expression
124    pub fn remove_watch(&mut self, id: u64) -> bool {
125        if let Some(pos) = self.watches.iter().position(|w| w.id == id) {
126            self.watches.remove(pos);
127            true
128        } else {
129            false
130        }
131    }
132}
133
134#[cfg(test)]
135mod tests {
136    use super::*;
137
138    #[test]
139    fn test_debug_context_creation() {
140        let agent_id = [1u8; 16];
141        let context = DebugContext::new(agent_id);
142
143        assert_eq!(context.agent_id, agent_id);
144        assert!(!context.enabled);
145        assert!(context.breakpoints.is_empty());
146        assert!(context.watches.is_empty());
147    }
148
149    #[test]
150    fn test_debug_context_enable_disable() {
151        let agent_id = [1u8; 16];
152        let mut context = DebugContext::new(agent_id);
153
154        assert!(!context.enabled);
155        context.enable();
156        assert!(context.enabled);
157        context.disable();
158        assert!(!context.enabled);
159    }
160
161    #[test]
162    fn test_debug_context_breakpoints() {
163        let agent_id = [1u8; 16];
164        let mut context = DebugContext::new(agent_id);
165
166        let bp_id = context.add_breakpoint("main".to_string(), None);
167        assert_eq!(context.breakpoints.len(), 1);
168
169        let removed = context.remove_breakpoint(bp_id);
170        assert!(removed);
171        assert_eq!(context.breakpoints.len(), 0);
172    }
173
174    #[test]
175    fn test_debug_context_watches() {
176        let agent_id = [1u8; 16];
177        let mut context = DebugContext::new(agent_id);
178
179        let watch_id = context.add_watch("variable_x".to_string());
180        assert_eq!(context.watches.len(), 1);
181
182        let removed = context.remove_watch(watch_id);
183        assert!(removed);
184        assert_eq!(context.watches.len(), 0);
185    }
186}