Skip to content

Commit

Permalink
feat(debugger): add uuid type support
Browse files Browse the repository at this point in the history
  • Loading branch information
godzie44 committed Mar 28, 2024
1 parent 1a81bcb commit 4c21351
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 5 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
* [breakpoints, steps, signals]((#stopping-and-continuing))
* multithread application support
* [data query expressions](#examining-data)
* support for a rust type system (collections, smart pointers, thread locals and other), not only for printing but also for interaction
* support for a rust type system (collections, smart pointers, thread locals and many others), not only for printing but also for interaction
* two ui types: console and [tui](#tui-interface), switch available in any moment
* [oracle](#oracles) as extension mechanism
* builtin [tokio oracle](#oracles) - like `tokio_console` but there is no need to make changes in the source codes
Expand Down
8 changes: 6 additions & 2 deletions examples/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions examples/vars/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ publish = false
[[bin]]
name = "vars"
path = "src/vars.rs"

[dependencies]
uuid = { version = "1.8.0", features = ["v4", "v7"] }
8 changes: 8 additions & 0 deletions examples/vars/src/vars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,13 @@ fn shadowing() {
let nop: Option<u8> = None;
}

fn uuid() {
let uuid_v4 = uuid::Uuid::new_v4();
let uuid_v7 = uuid::Uuid::new_v7(uuid::timestamp::Timestamp::from_rfc4122(1, 1));

let nop: Option<u8> = None;
}

pub fn main() {
scalar_types();
compound_types();
Expand Down Expand Up @@ -476,4 +483,5 @@ pub fn main() {
zst();
inner_static();
shadowing();
uuid();
}
9 changes: 9 additions & 0 deletions src/debugger/variable/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ impl VariableIR {
SpecializedVariableIR::RefCell { original, .. } => &original.identity,
SpecializedVariableIR::Rc { original, .. } => &original.identity,
SpecializedVariableIR::Arc { original, .. } => &original.identity,
SpecializedVariableIR::Uuid { original, .. } => &original.identity,
},
VariableIR::Subroutine(s) => &s.identity,
VariableIR::CModifiedVariable(v) => &v.identity,
Expand Down Expand Up @@ -483,6 +484,7 @@ impl VariableIR {
SpecializedVariableIR::RefCell { original, .. } => &mut original.identity,
SpecializedVariableIR::Rc { original, .. } => &mut original.identity,
SpecializedVariableIR::Arc { original, .. } => &mut original.identity,
SpecializedVariableIR::Uuid { original, .. } => &mut original.identity,
},
VariableIR::Subroutine(s) => &mut s.identity,
VariableIR::CModifiedVariable(v) => &mut v.identity,
Expand Down Expand Up @@ -1064,6 +1066,12 @@ impl<'a> VariableParser<'a> {
return VariableIR::Specialized(parser_ext.parse_arc(struct_var));
};

if struct_name.as_ref().map(|name| name == "Uuid") == Some(true)
&& type_ns_h.contains(&["uuid"])
{
return VariableIR::Specialized(parser_ext.parse_uuid(struct_var));
};

VariableIR::Struct(struct_var)
}
TypeDeclaration::Array(decl) => {
Expand Down Expand Up @@ -1215,6 +1223,7 @@ impl<'a> Iterator for BfsIterator<'a> {
.for_each(|member| self.queue.push_back(member));
}
SpecializedVariableIR::Rc { .. } | SpecializedVariableIR::Arc { .. } => {}
SpecializedVariableIR::Uuid { .. } => {}
},
_ => {}
}
Expand Down
10 changes: 10 additions & 0 deletions src/debugger/variable/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ impl RenderRepr for VariableIR {
| SpecializedVariableIR::RefCell { original, .. } => &original.type_name,
SpecializedVariableIR::Rc { original, .. }
| SpecializedVariableIR::Arc { original, .. } => &original.type_name,
SpecializedVariableIR::Uuid { original, .. } => &original.type_name,
},
VariableIR::Subroutine(_) => {
// currently this line is unreachable cause dereference fn pointer is forbidden
Expand Down Expand Up @@ -213,6 +214,15 @@ impl RenderRepr for VariableIR {
ValueLayout::Referential { addr: ptr }
}
},
SpecializedVariableIR::Uuid { value, original } => match value {
None => ValueLayout::Structure {
members: original.members.as_ref(),
},
Some(array) => {
let uuid = uuid::Uuid::from_slice(array).expect("infallible");
ValueLayout::PreRendered(Cow::Owned(uuid.to_string()))
}
},
},
VariableIR::Subroutine(_) => {
// currently this line is unreachable a cause dereference fn pointer is forbidden
Expand Down
41 changes: 41 additions & 0 deletions src/debugger/variable/specialization/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ pub enum SpecializedVariableIR {
value: Option<PointerVariable>,
original: StructVariable,
},
Uuid {
value: Option<[u8; 16]>,
original: StructVariable,
},
}

pub struct VariableParserExtension<'a> {
Expand Down Expand Up @@ -860,6 +864,43 @@ impl<'a> VariableParserExtension<'a> {
})
.ok_or(IncompleteInterp("Arc"))?)
}

pub fn parse_uuid(&self, structure: StructVariable) -> SpecializedVariableIR {
SpecializedVariableIR::Uuid {
value: weak_error!(self
.parse_uuid_inner(&structure)
.context("Uuid interpretation")),
original: structure,
}
}

fn parse_uuid_inner(&self, structure: &StructVariable) -> Result<[u8; 16], ParsingError> {
let member0 = structure.members.first().ok_or(FieldNotFound("member 0"))?;
let VariableIR::Array(arr) = member0 else {
return Err(UnexpectedType("uuid struct member must be an array").into());
};
let items = arr
.items
.as_ref()
.ok_or(AssumeError::NoData("uuid items"))?;
if items.len() != 16 {
return Err(AssumeError::UnexpectedType("uuid struct member must be [u8; 16]").into());
}

let mut bytes_repr = [0; 16];
for (i, item) in items.iter().enumerate() {
let VariableIR::Scalar(ScalarVariable {
value: Some(SupportedScalar::U8(byte)),
..
}) = item
else {
return Err(UnexpectedType("uuid struct member must be [u8; 16]").into());
};
bytes_repr[i] = *byte;
}

Ok(bytes_repr)
}
}

fn extract_capacity(eval_ctx: &EvaluationContext, ir: &VariableIR) -> Result<usize, ParsingError> {
Expand Down
34 changes: 32 additions & 2 deletions tests/debugger/variables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,14 @@ fn assert_arc(var: &VariableIR, exp_name: &str, exp_type: &str) {
assert_eq!(var.r#type(), exp_type);
}

fn assert_uuid(var: &VariableIR, exp_name: &str, exp_type: &str) {
let VariableIR::Specialized(variable::SpecializedVariableIR::Uuid { .. }) = var else {
panic!("not an uuid");
};
assert_eq!(var.name(), exp_name);
assert_eq!(var.r#type(), exp_type);
}

#[test]
#[serial]
fn test_read_scalar_variables() {
Expand Down Expand Up @@ -2232,7 +2240,7 @@ fn test_read_static_in_fn_variable() {
// brkpt in function where static is declared
debugger.set_breakpoint_at_line("vars.rs", 438).unwrap();
// brkpt outside function where static is declared
debugger.set_breakpoint_at_line("vars.rs", 478).unwrap();
debugger.set_breakpoint_at_line("vars.rs", 485).unwrap();

debugger.start_debugee().unwrap();
assert_eq!(info.line.take(), Some(438));
Expand All @@ -2251,7 +2259,7 @@ fn test_read_static_in_fn_variable() {
);

debugger.continue_debugee().unwrap();
assert_eq!(info.line.take(), Some(478));
assert_eq!(info.line.take(), Some(485));

let vars = debugger
.read_variable(Expression::Variable(VariableSelector::Name {
Expand Down Expand Up @@ -2393,3 +2401,25 @@ fn test_cast_pointers() {
debugger.continue_debugee().unwrap();
assert_no_proc!(debugee_pid);
}

#[test]
#[serial]
fn test_read_uuid() {
let process = prepare_debugee_process(VARS_APP, &[]);
let debugee_pid = process.pid();
let info = DebugeeRunInfo::default();
let builder = DebuggerBuilder::new().with_hooks(TestHooks::new(info.clone()));
let mut debugger = builder.build(process).unwrap();

debugger.set_breakpoint_at_line("vars.rs", 453).unwrap();

debugger.start_debugee().unwrap();
assert_eq!(info.line.take(), Some(453));

let vars = debugger.read_local_variables().unwrap();
assert_uuid(&vars[0], "uuid_v4", "Uuid");
assert_uuid(&vars[1], "uuid_v7", "Uuid");

debugger.continue_debugee().unwrap();
assert_no_proc!(debugee_pid);
}

0 comments on commit 4c21351

Please sign in to comment.