From 3f5b42c0203cb316685ecbc95f940c58e71ff699 Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Sat, 12 Jul 2025 01:38:56 +0300 Subject: [PATCH 01/30] feat(stream_api): introduced trait TraceWriter It does not support streaming, yet. --- runtime_tracing/src/lib.rs | 2 +- runtime_tracing/src/tracer.rs | 145 +++++++++++++++++++++----------- runtime_tracing_cli/src/main.rs | 3 +- 3 files changed, 96 insertions(+), 54 deletions(-) diff --git a/runtime_tracing/src/lib.rs b/runtime_tracing/src/lib.rs index c71252c..e1ba466 100644 --- a/runtime_tracing/src/lib.rs +++ b/runtime_tracing/src/lib.rs @@ -12,7 +12,7 @@ mod tracer; mod types; mod base64; mod capnptrace; -pub use crate::tracer::{Tracer, TraceEventsFileFormat, NONE_TYPE_ID, NONE_VALUE}; +pub use crate::tracer::{Tracer, TraceWriter, TraceEventsFileFormat, NONE_TYPE_ID, NONE_VALUE}; pub use crate::types::*; pub mod trace_capnp { diff --git a/runtime_tracing/src/tracer.rs b/runtime_tracing/src/tracer.rs index ac2f80f..effaa72 100644 --- a/runtime_tracing/src/tracer.rs +++ b/runtime_tracing/src/tracer.rs @@ -14,6 +14,48 @@ use crate::types::{ }; use crate::RValue; +pub trait TraceWriter { + fn start(&mut self, path: &Path, line: Line); + fn ensure_path_id(&mut self, path: &Path) -> PathId; + fn ensure_function_id(&mut self, function_name: &str, path: &Path, line: Line) -> FunctionId; + fn ensure_type_id(&mut self, kind: TypeKind, lang_type: &str) -> TypeId; + fn ensure_raw_type_id(&mut self, typ: TypeRecord) -> TypeId; + fn ensure_variable_id(&mut self, variable_name: &str) -> VariableId; + fn register_path(&mut self, path: &Path); + fn register_function(&mut self, name: &str, path: &Path, line: Line); + fn register_step(&mut self, path: &Path, line: Line); + fn register_call(&mut self, function_id: FunctionId, args: Vec); + fn arg(&mut self, name: &str, value: ValueRecord) -> FullValueRecord; + fn register_return(&mut self, return_value: ValueRecord); + // TODO: add metadata arg + fn register_special_event(&mut self, kind: EventLogKind, content: &str); + fn to_raw_type(&self, kind: TypeKind, lang_type: &str) -> TypeRecord; + fn register_type(&mut self, kind: TypeKind, lang_type: &str); + fn register_raw_type(&mut self, typ: TypeRecord); + fn register_asm(&mut self, instructions: &[String]); + fn register_variable_with_full_value(&mut self, name: &str, value: ValueRecord); + fn register_variable_name(&mut self, variable_name: &str); + fn register_full_value(&mut self, variable_id: VariableId, value: ValueRecord); + fn register_compound_value(&mut self, place: Place, value: ValueRecord); + fn register_cell_value(&mut self, place: Place, value: ValueRecord); + fn assign_compound_item(&mut self, place: Place, index: usize, item_place: Place); + fn assign_cell(&mut self, place: Place, new_value: ValueRecord); + fn register_variable(&mut self, variable_name: &str, place: Place); + fn drop_variable(&mut self, variable_name: &str); + // history event helpers + fn assign(&mut self, variable_name: &str, rvalue: RValue, pass_by: PassBy); + fn bind_variable(&mut self, variable_name: &str, place: Place); + fn drop_variables(&mut self, variable_names: &[String]); + fn simple_rvalue(&mut self, variable_name: &str) -> RValue; + fn compound_rvalue(&mut self, variable_dependencies: &[String]) -> RValue; + fn drop_last_step(&mut self); + + fn store_trace_metadata(&self, path: &Path) -> Result<(), Box>; + fn store_trace_events(&self, path: &Path, format: TraceEventsFileFormat) -> Result<(), Box>; + fn store_trace_paths(&self, path: &Path) -> Result<(), Box>; +} + + /// State machine used to record [`TraceLowLevelEvent`]s. /// /// A `Tracer` instance accumulates events and can store them on disk via the @@ -69,8 +111,25 @@ impl Tracer { } } + pub fn load_trace_events(&mut self, path: &Path, format: TraceEventsFileFormat) -> Result<(), Box> { + match format { + TraceEventsFileFormat::Json => { + let json = std::fs::read_to_string(path)?; + self.events = serde_json::from_str(&json)?; + } + TraceEventsFileFormat::Binary => { + let file = fs::File::open(path)?; + let mut buf_reader = BufReader::new(file); + self.events = crate::capnptrace::read_trace(&mut buf_reader)?; + } + } + Ok(()) + } +} + +impl TraceWriter for Tracer { /// Begin tracing of a program starting at the given source location. - pub fn start(&mut self, path: &Path, line: Line) { + fn start(&mut self, path: &Path, line: Line) { let function_id = self.ensure_function_id("", path, line); self.register_call(function_id, vec![]); assert!(function_id == TOP_LEVEL_FUNCTION_ID); @@ -84,7 +143,7 @@ impl Tracer { assert!(NONE_TYPE_ID == self.ensure_type_id(TypeKind::None, "None")); } - pub fn ensure_path_id(&mut self, path: &Path) -> PathId { + fn ensure_path_id(&mut self, path: &Path) -> PathId { if !self.paths.contains_key(path) { self.paths.insert(path.to_path_buf(), PathId(self.paths.len())); self.register_path(path); @@ -92,7 +151,7 @@ impl Tracer { *self.paths.get(path).unwrap() } - pub fn ensure_function_id(&mut self, function_name: &str, path: &Path, line: Line) -> FunctionId { + fn ensure_function_id(&mut self, function_name: &str, path: &Path, line: Line) -> FunctionId { if !self.functions.contains_key(function_name) { // same function names for different path line? TODO self.functions.insert(function_name.to_string(), FunctionId(self.functions.len())); @@ -101,12 +160,12 @@ impl Tracer { *self.functions.get(function_name).unwrap() } - pub fn ensure_type_id(&mut self, kind: TypeKind, lang_type: &str) -> TypeId { + fn ensure_type_id(&mut self, kind: TypeKind, lang_type: &str) -> TypeId { let typ = self.to_raw_type(kind, lang_type); self.ensure_raw_type_id(typ) } - pub fn ensure_raw_type_id(&mut self, typ: TypeRecord) -> TypeId { + fn ensure_raw_type_id(&mut self, typ: TypeRecord) -> TypeId { if !self.types.contains_key(&typ.lang_type) { self.types.insert(typ.lang_type.clone(), TypeId(self.types.len())); self.register_raw_type(typ.clone()); @@ -114,7 +173,7 @@ impl Tracer { *self.types.get(&typ.lang_type).unwrap() } - pub fn ensure_variable_id(&mut self, variable_name: &str) -> VariableId { + fn ensure_variable_id(&mut self, variable_name: &str) -> VariableId { if !self.variables.contains_key(variable_name) { self.variables.insert(variable_name.to_string(), VariableId(self.variables.len())); self.register_variable_name(variable_name); @@ -122,12 +181,12 @@ impl Tracer { *self.variables.get(variable_name).unwrap() } - pub fn register_path(&mut self, path: &Path) { + fn register_path(&mut self, path: &Path) { self.path_list.push(path.to_path_buf()); self.events.push(TraceLowLevelEvent::Path(path.to_path_buf())); } - pub fn register_function(&mut self, name: &str, path: &Path, line: Line) { + fn register_function(&mut self, name: &str, path: &Path, line: Line) { let path_id = self.ensure_path_id(path); self.function_list.push((name.to_string(), path_id, line)); self.events.push(TraceLowLevelEvent::Function(FunctionRecord { @@ -137,12 +196,12 @@ impl Tracer { })); } - pub fn register_step(&mut self, path: &Path, line: Line) { + fn register_step(&mut self, path: &Path, line: Line) { let path_id = self.ensure_path_id(path); self.events.push(TraceLowLevelEvent::Step(StepRecord { path_id, line })); } - pub fn register_call(&mut self, function_id: FunctionId, args: Vec) { + fn register_call(&mut self, function_id: FunctionId, args: Vec) { // register a step for each call, the backend expects this for // non-toplevel calls, so // we ensure it directly from register_call @@ -160,17 +219,16 @@ impl Tracer { self.events.push(TraceLowLevelEvent::Call(CallRecord { function_id, args })); } - pub fn arg(&mut self, name: &str, value: ValueRecord) -> FullValueRecord { + fn arg(&mut self, name: &str, value: ValueRecord) -> FullValueRecord { let variable_id = self.ensure_variable_id(name); FullValueRecord { variable_id, value } } - pub fn register_return(&mut self, return_value: ValueRecord) { + fn register_return(&mut self, return_value: ValueRecord) { self.events.push(TraceLowLevelEvent::Return(ReturnRecord { return_value })); } - // TODO: add metadata arg - pub fn register_special_event(&mut self, kind: EventLogKind, content: &str) { + fn register_special_event(&mut self, kind: EventLogKind, content: &str) { self.events.push(TraceLowLevelEvent::Event(RecordEvent { kind, metadata: "".to_string(), @@ -178,7 +236,7 @@ impl Tracer { })); } - pub fn to_raw_type(&self, kind: TypeKind, lang_type: &str) -> TypeRecord { + fn to_raw_type(&self, kind: TypeKind, lang_type: &str) -> TypeRecord { TypeRecord { kind, lang_type: lang_type.to_string(), @@ -186,64 +244,64 @@ impl Tracer { } } - pub fn register_type(&mut self, kind: TypeKind, lang_type: &str) { + fn register_type(&mut self, kind: TypeKind, lang_type: &str) { let typ = self.to_raw_type(kind, lang_type); self.events.push(TraceLowLevelEvent::Type(typ)); } - pub fn register_raw_type(&mut self, typ: TypeRecord) { + fn register_raw_type(&mut self, typ: TypeRecord) { self.events.push(TraceLowLevelEvent::Type(typ)); } - pub fn register_asm(&mut self, instructions: &[String]) { + fn register_asm(&mut self, instructions: &[String]) { self.events.push(TraceLowLevelEvent::Asm(instructions.to_vec())); } - pub fn register_variable_with_full_value(&mut self, name: &str, value: ValueRecord) { + fn register_variable_with_full_value(&mut self, name: &str, value: ValueRecord) { let variable_id = self.ensure_variable_id(name); self.register_full_value(variable_id, value); } - pub fn register_variable_name(&mut self, variable_name: &str) { + fn register_variable_name(&mut self, variable_name: &str) { self.events.push(TraceLowLevelEvent::VariableName(variable_name.to_string())); } - pub fn register_full_value(&mut self, variable_id: VariableId, value: ValueRecord) { + fn register_full_value(&mut self, variable_id: VariableId, value: ValueRecord) { self.events.push(TraceLowLevelEvent::Value(FullValueRecord { variable_id, value })); } - pub fn register_compound_value(&mut self, place: Place, value: ValueRecord) { + fn register_compound_value(&mut self, place: Place, value: ValueRecord) { self.events.push(TraceLowLevelEvent::CompoundValue(CompoundValueRecord { place, value })); } - pub fn register_cell_value(&mut self, place: Place, value: ValueRecord) { + fn register_cell_value(&mut self, place: Place, value: ValueRecord) { self.events.push(TraceLowLevelEvent::CellValue(CellValueRecord { place, value })); } - pub fn assign_compound_item(&mut self, place: Place, index: usize, item_place: Place) { + fn assign_compound_item(&mut self, place: Place, index: usize, item_place: Place) { self.events.push(TraceLowLevelEvent::AssignCompoundItem(AssignCompoundItemRecord { place, index, item_place, })); } - pub fn assign_cell(&mut self, place: Place, new_value: ValueRecord) { + fn assign_cell(&mut self, place: Place, new_value: ValueRecord) { self.events.push(TraceLowLevelEvent::AssignCell(AssignCellRecord { place, new_value })); } - pub fn register_variable(&mut self, variable_name: &str, place: Place) { + fn register_variable(&mut self, variable_name: &str, place: Place) { let variable_id = self.ensure_variable_id(variable_name); self.events .push(TraceLowLevelEvent::VariableCell(VariableCellRecord { variable_id, place })); } - pub fn drop_variable(&mut self, variable_name: &str) { + fn drop_variable(&mut self, variable_name: &str) { let variable_id = self.ensure_variable_id(variable_name); self.events.push(TraceLowLevelEvent::DropVariable(variable_id)); } // history event helpers - pub fn assign(&mut self, variable_name: &str, rvalue: RValue, pass_by: PassBy) { + fn assign(&mut self, variable_name: &str, rvalue: RValue, pass_by: PassBy) { let variable_id = self.ensure_variable_id(variable_name); self.events.push(TraceLowLevelEvent::Assignment(AssignmentRecord { to: variable_id, @@ -252,13 +310,13 @@ impl Tracer { })); } - pub fn bind_variable(&mut self, variable_name: &str, place: Place) { + fn bind_variable(&mut self, variable_name: &str, place: Place) { let variable_id = self.ensure_variable_id(variable_name); self.events .push(TraceLowLevelEvent::BindVariable(crate::BindVariableRecord { variable_id, place })); } - pub fn drop_variables(&mut self, variable_names: &[String]) { + fn drop_variables(&mut self, variable_names: &[String]) { let variable_ids: Vec = variable_names .to_vec() .iter() @@ -267,12 +325,12 @@ impl Tracer { self.events.push(TraceLowLevelEvent::DropVariables(variable_ids)) } - pub fn simple_rvalue(&mut self, variable_name: &str) -> RValue { + fn simple_rvalue(&mut self, variable_name: &str) -> RValue { let variable_id = self.ensure_variable_id(variable_name); RValue::Simple(variable_id) } - pub fn compound_rvalue(&mut self, variable_dependencies: &[String]) -> RValue { + fn compound_rvalue(&mut self, variable_dependencies: &[String]) -> RValue { let variable_ids: Vec = variable_dependencies .to_vec() .iter() @@ -281,11 +339,11 @@ impl Tracer { RValue::Compound(variable_ids) } - pub fn drop_last_step(&mut self) { + fn drop_last_step(&mut self) { self.events.push(TraceLowLevelEvent::DropLastStep); } - pub fn store_trace_metadata(&self, path: &Path) -> Result<(), Box> { + fn store_trace_metadata(&self, path: &Path) -> Result<(), Box> { let trace_metadata = TraceMetadata { program: self.program.clone(), args: self.args.clone(), @@ -296,22 +354,7 @@ impl Tracer { Ok(()) } - pub fn load_trace_events(&mut self, path: &Path, format: TraceEventsFileFormat) -> Result<(), Box> { - match format { - TraceEventsFileFormat::Json => { - let json = std::fs::read_to_string(path)?; - self.events = serde_json::from_str(&json)?; - } - TraceEventsFileFormat::Binary => { - let file = fs::File::open(path)?; - let mut buf_reader = BufReader::new(file); - self.events = crate::capnptrace::read_trace(&mut buf_reader)?; - } - } - Ok(()) - } - - pub fn store_trace_events(&self, path: &Path, format: TraceEventsFileFormat) -> Result<(), Box> { + fn store_trace_events(&self, path: &Path, format: TraceEventsFileFormat) -> Result<(), Box> { match format { TraceEventsFileFormat::Json => { let json = serde_json::to_string(&self.events)?; @@ -325,7 +368,7 @@ impl Tracer { Ok(()) } - pub fn store_trace_paths(&self, path: &Path) -> Result<(), Box> { + fn store_trace_paths(&self, path: &Path) -> Result<(), Box> { let json = serde_json::to_string(&self.path_list)?; fs::write(path, json)?; Ok(()) diff --git a/runtime_tracing_cli/src/main.rs b/runtime_tracing_cli/src/main.rs index ce12260..dbad7ee 100644 --- a/runtime_tracing_cli/src/main.rs +++ b/runtime_tracing_cli/src/main.rs @@ -1,8 +1,7 @@ use std::path::Path; use clap::{Args, Parser, Subcommand}; -use runtime_tracing::{TraceEventsFileFormat, Tracer}; - +use runtime_tracing::{TraceEventsFileFormat, Tracer, TraceWriter}; use crate::fmt_trace_cmd::FmtTraceCommand; mod fmt_trace_cmd; From 7213328780ec8094441af372b307d0002016f51b Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Sat, 12 Jul 2025 01:48:48 +0300 Subject: [PATCH 02/30] feat(stream_api): added function create_trace_writer --- runtime_tracing/src/tracer.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/runtime_tracing/src/tracer.rs b/runtime_tracing/src/tracer.rs index effaa72..7d38ae4 100644 --- a/runtime_tracing/src/tracer.rs +++ b/runtime_tracing/src/tracer.rs @@ -374,3 +374,7 @@ impl TraceWriter for Tracer { Ok(()) } } + +pub fn create_trace_writer(program: &str, args: &[String], format: TraceEventsFileFormat) -> Box { + Box::new(Tracer::new(program, args)) +} From aeb455f71bd245e0fa49d142461806d871507be9 Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Mon, 14 Jul 2025 17:24:21 +0300 Subject: [PATCH 03/30] feat(stream_api): added function begin_writing_trace_events() to the TraceWriter trait --- runtime_tracing/src/tracer.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/runtime_tracing/src/tracer.rs b/runtime_tracing/src/tracer.rs index 7d38ae4..e40321e 100644 --- a/runtime_tracing/src/tracer.rs +++ b/runtime_tracing/src/tracer.rs @@ -15,6 +15,8 @@ use crate::types::{ use crate::RValue; pub trait TraceWriter { + fn begin_writing_trace_events(&mut self, path: &Path); + fn start(&mut self, path: &Path, line: Line); fn ensure_path_id(&mut self, path: &Path) -> PathId; fn ensure_function_id(&mut self, function_name: &str, path: &Path, line: Line) -> FunctionId; @@ -128,6 +130,9 @@ impl Tracer { } impl TraceWriter for Tracer { + fn begin_writing_trace_events(&mut self, path: &Path) { + } + /// Begin tracing of a program starting at the given source location. fn start(&mut self, path: &Path, line: Line) { let function_id = self.ensure_function_id("", path, line); From 87212131e936e16ffa375790aa3895dcf42a6825 Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Mon, 14 Jul 2025 17:33:32 +0300 Subject: [PATCH 04/30] feat(stream_api): added field Tracer::format --- runtime_tracing/src/tracer.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/runtime_tracing/src/tracer.rs b/runtime_tracing/src/tracer.rs index e40321e..4336bae 100644 --- a/runtime_tracing/src/tracer.rs +++ b/runtime_tracing/src/tracer.rs @@ -77,6 +77,8 @@ pub struct Tracer { functions: HashMap, variables: HashMap, types: HashMap, + + format: TraceEventsFileFormat, } pub enum TraceEventsFileFormat { @@ -110,6 +112,8 @@ impl Tracer { functions: HashMap::new(), variables: HashMap::new(), types: HashMap::new(), + + format: TraceEventsFileFormat::Binary, } } From 93942a5752cad6e20a9971037dd7e38e1f142556 Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Mon, 14 Jul 2025 17:36:33 +0300 Subject: [PATCH 05/30] feat(stream_api): set format in create_trace_writer() --- runtime_tracing/src/tracer.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/runtime_tracing/src/tracer.rs b/runtime_tracing/src/tracer.rs index 4336bae..41181e0 100644 --- a/runtime_tracing/src/tracer.rs +++ b/runtime_tracing/src/tracer.rs @@ -117,6 +117,10 @@ impl Tracer { } } + pub fn set_format(&mut self, format: TraceEventsFileFormat) { + self.format = format; + } + pub fn load_trace_events(&mut self, path: &Path, format: TraceEventsFileFormat) -> Result<(), Box> { match format { TraceEventsFileFormat::Json => { @@ -385,5 +389,7 @@ impl TraceWriter for Tracer { } pub fn create_trace_writer(program: &str, args: &[String], format: TraceEventsFileFormat) -> Box { - Box::new(Tracer::new(program, args)) + let mut result = Box::new(Tracer::new(program, args)); + result.set_format(format); + result } From 899d70ec683562954f166a10d39b9a73db7b41a4 Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Mon, 14 Jul 2025 17:39:21 +0300 Subject: [PATCH 06/30] feat(stream_api): added trait TraceReader --- runtime_tracing/src/tracer.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/runtime_tracing/src/tracer.rs b/runtime_tracing/src/tracer.rs index 41181e0..9726367 100644 --- a/runtime_tracing/src/tracer.rs +++ b/runtime_tracing/src/tracer.rs @@ -14,6 +14,10 @@ use crate::types::{ }; use crate::RValue; +pub trait TraceReader { + fn load_trace_events(&mut self, path: &Path, format: TraceEventsFileFormat) -> Result, Box>; +} + pub trait TraceWriter { fn begin_writing_trace_events(&mut self, path: &Path); From d6e7f0e5ee64c34f7aa6e0d83805d9c3c8950832 Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Mon, 14 Jul 2025 17:50:03 +0300 Subject: [PATCH 07/30] feat(stream_api): implemented trace readers for both the json and binary format --- runtime_tracing/src/tracer.rs | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/runtime_tracing/src/tracer.rs b/runtime_tracing/src/tracer.rs index 9726367..9352379 100644 --- a/runtime_tracing/src/tracer.rs +++ b/runtime_tracing/src/tracer.rs @@ -15,7 +15,28 @@ use crate::types::{ use crate::RValue; pub trait TraceReader { - fn load_trace_events(&mut self, path: &Path, format: TraceEventsFileFormat) -> Result, Box>; + fn load_trace_events(&mut self, path: &Path) -> Result, Box>; +} + +pub struct JsonTraceReader { +} + +impl TraceReader for JsonTraceReader { + fn load_trace_events(&mut self, path: &Path) -> Result, Box> { + let json = std::fs::read_to_string(path)?; + Ok(serde_json::from_str(&json)?) + } +} + +pub struct BinaryTraceReader { +} + +impl TraceReader for BinaryTraceReader { + fn load_trace_events(&mut self, path: &Path) -> Result, Box> { + let file = fs::File::open(path)?; + let mut buf_reader = BufReader::new(file); + Ok(crate::capnptrace::read_trace(&mut buf_reader)?) + } } pub trait TraceWriter { @@ -392,6 +413,18 @@ impl TraceWriter for Tracer { } } +pub fn create_trace_reader(format: TraceEventsFileFormat) -> Box { + match format { + TraceEventsFileFormat::Json => { + Box::new(JsonTraceReader { } ) + } + TraceEventsFileFormat::Binary => { + Box::new(BinaryTraceReader { } ) + } + } + +} + pub fn create_trace_writer(program: &str, args: &[String], format: TraceEventsFileFormat) -> Box { let mut result = Box::new(Tracer::new(program, args)); result.set_format(format); From adf777aad8ae8a51593d95da0d616f376b70ab2b Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Tue, 15 Jul 2025 01:05:31 +0300 Subject: [PATCH 08/30] feat(stream_api): added and implemented method TraceWriter::add_event() --- runtime_tracing/src/tracer.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/runtime_tracing/src/tracer.rs b/runtime_tracing/src/tracer.rs index 9352379..3a0860b 100644 --- a/runtime_tracing/src/tracer.rs +++ b/runtime_tracing/src/tracer.rs @@ -77,6 +77,8 @@ pub trait TraceWriter { fn compound_rvalue(&mut self, variable_dependencies: &[String]) -> RValue; fn drop_last_step(&mut self); + fn add_event(&mut self, event: TraceLowLevelEvent); + fn store_trace_metadata(&self, path: &Path) -> Result<(), Box>; fn store_trace_events(&self, path: &Path, format: TraceEventsFileFormat) -> Result<(), Box>; fn store_trace_paths(&self, path: &Path) -> Result<(), Box>; @@ -381,6 +383,10 @@ impl TraceWriter for Tracer { self.events.push(TraceLowLevelEvent::DropLastStep); } + fn add_event(&mut self, event: TraceLowLevelEvent) { + self.events.push(event) + } + fn store_trace_metadata(&self, path: &Path) -> Result<(), Box> { let trace_metadata = TraceMetadata { program: self.program.clone(), From 79030a24da033eb6ca453234681ff716effd53aa Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Tue, 15 Jul 2025 01:12:29 +0300 Subject: [PATCH 09/30] feat(stream_api): added and implemented method TraceWriter::append_event() --- runtime_tracing/src/tracer.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/runtime_tracing/src/tracer.rs b/runtime_tracing/src/tracer.rs index 3a0860b..64f3d3e 100644 --- a/runtime_tracing/src/tracer.rs +++ b/runtime_tracing/src/tracer.rs @@ -78,6 +78,7 @@ pub trait TraceWriter { fn drop_last_step(&mut self); fn add_event(&mut self, event: TraceLowLevelEvent); + fn append_events(&mut self, events: &mut Vec); fn store_trace_metadata(&self, path: &Path) -> Result<(), Box>; fn store_trace_events(&self, path: &Path, format: TraceEventsFileFormat) -> Result<(), Box>; @@ -387,6 +388,10 @@ impl TraceWriter for Tracer { self.events.push(event) } + fn append_events(&mut self, events: &mut Vec) { + self.events.append(events); + } + fn store_trace_metadata(&self, path: &Path) -> Result<(), Box> { let trace_metadata = TraceMetadata { program: self.program.clone(), From fb48b0abcdf803f0ba2beddf1e71df11cb74803a Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Tue, 15 Jul 2025 01:15:44 +0300 Subject: [PATCH 10/30] feat(stream_api): export create_trace_reader and create_trace_writer from runtime_tracing --- runtime_tracing/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime_tracing/src/lib.rs b/runtime_tracing/src/lib.rs index e1ba466..4af9aeb 100644 --- a/runtime_tracing/src/lib.rs +++ b/runtime_tracing/src/lib.rs @@ -12,7 +12,7 @@ mod tracer; mod types; mod base64; mod capnptrace; -pub use crate::tracer::{Tracer, TraceWriter, TraceEventsFileFormat, NONE_TYPE_ID, NONE_VALUE}; +pub use crate::tracer::{Tracer, TraceWriter, TraceEventsFileFormat, NONE_TYPE_ID, NONE_VALUE, create_trace_reader, create_trace_writer}; pub use crate::types::*; pub mod trace_capnp { From 342c795dfcf685fe398d86658af56a152862d2d3 Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Tue, 15 Jul 2025 18:00:26 +0300 Subject: [PATCH 11/30] feat(stream_api): derive debug, clone and copy for the TraceEventsFileFormat enum --- runtime_tracing/src/tracer.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime_tracing/src/tracer.rs b/runtime_tracing/src/tracer.rs index 64f3d3e..86e1734 100644 --- a/runtime_tracing/src/tracer.rs +++ b/runtime_tracing/src/tracer.rs @@ -109,6 +109,7 @@ pub struct Tracer { format: TraceEventsFileFormat, } +#[derive(Debug, Clone, Copy)] pub enum TraceEventsFileFormat { Json, Binary From 361b07cd6dd68fa297c5630f778f37f9b290b35d Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Tue, 15 Jul 2025 18:08:07 +0300 Subject: [PATCH 12/30] feat(stream_api): use the new API in runtime_tracing_cli --- runtime_tracing_cli/src/main.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/runtime_tracing_cli/src/main.rs b/runtime_tracing_cli/src/main.rs index dbad7ee..c406ee0 100644 --- a/runtime_tracing_cli/src/main.rs +++ b/runtime_tracing_cli/src/main.rs @@ -1,7 +1,7 @@ use std::path::Path; use clap::{Args, Parser, Subcommand}; -use runtime_tracing::{TraceEventsFileFormat, Tracer, TraceWriter}; +use runtime_tracing::{create_trace_reader, create_trace_writer, TraceEventsFileFormat, TraceWriter, Tracer}; use crate::fmt_trace_cmd::FmtTraceCommand; mod fmt_trace_cmd; @@ -44,9 +44,12 @@ fn main() { RuntimeTracingCliCommand::Convert(convert_command) => { let input_file_format = determine_file_format_from_name(&convert_command.input_file).unwrap(); let output_file_format = determine_file_format_from_name(&convert_command.output_file).unwrap(); - let mut trace = Tracer::new("", &[]); - trace.load_trace_events(Path::new(&convert_command.input_file), input_file_format).unwrap(); - trace.store_trace_events(Path::new(&convert_command.output_file), output_file_format).unwrap(); + let mut trace_reader = create_trace_reader(input_file_format); + let mut trace_writer = create_trace_writer("", &[], output_file_format); + let mut trace_events = trace_reader.load_trace_events(Path::new(&convert_command.input_file)).unwrap(); + trace_writer.begin_writing_trace_events(Path::new(&convert_command.output_file)); + trace_writer.append_events(&mut trace_events); + trace_writer.store_trace_events(Path::new(&convert_command.output_file), output_file_format).unwrap(); }, RuntimeTracingCliCommand::FormatTrace(fmt_trace_cmd) => { fmt_trace_cmd::run(fmt_trace_cmd); From 40a9ac6e741092b31396eb4888db2d368221461e Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Tue, 15 Jul 2025 18:11:23 +0300 Subject: [PATCH 13/30] feat(stream_api): return Result in TraceWriter::begin_writing_trace_events() --- runtime_tracing/src/tracer.rs | 5 +++-- runtime_tracing_cli/src/main.rs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/runtime_tracing/src/tracer.rs b/runtime_tracing/src/tracer.rs index 86e1734..b083b9f 100644 --- a/runtime_tracing/src/tracer.rs +++ b/runtime_tracing/src/tracer.rs @@ -40,7 +40,7 @@ impl TraceReader for BinaryTraceReader { } pub trait TraceWriter { - fn begin_writing_trace_events(&mut self, path: &Path); + fn begin_writing_trace_events(&mut self, path: &Path) -> Result<(), Box>; fn start(&mut self, path: &Path, line: Line); fn ensure_path_id(&mut self, path: &Path) -> PathId; @@ -167,7 +167,8 @@ impl Tracer { } impl TraceWriter for Tracer { - fn begin_writing_trace_events(&mut self, path: &Path) { + fn begin_writing_trace_events(&mut self, path: &Path) -> Result<(), Box> { + Ok(()) } /// Begin tracing of a program starting at the given source location. diff --git a/runtime_tracing_cli/src/main.rs b/runtime_tracing_cli/src/main.rs index c406ee0..1537a30 100644 --- a/runtime_tracing_cli/src/main.rs +++ b/runtime_tracing_cli/src/main.rs @@ -47,7 +47,7 @@ fn main() { let mut trace_reader = create_trace_reader(input_file_format); let mut trace_writer = create_trace_writer("", &[], output_file_format); let mut trace_events = trace_reader.load_trace_events(Path::new(&convert_command.input_file)).unwrap(); - trace_writer.begin_writing_trace_events(Path::new(&convert_command.output_file)); + trace_writer.begin_writing_trace_events(Path::new(&convert_command.output_file)).unwrap(); trace_writer.append_events(&mut trace_events); trace_writer.store_trace_events(Path::new(&convert_command.output_file), output_file_format).unwrap(); }, From 98211978bb7f13b75c9b083545924d60cfb68504 Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Tue, 15 Jul 2025 18:18:34 +0300 Subject: [PATCH 14/30] feat(stream_api): store the path in begin_writing_trace_events --- runtime_tracing/src/tracer.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/runtime_tracing/src/tracer.rs b/runtime_tracing/src/tracer.rs index b083b9f..b3455ab 100644 --- a/runtime_tracing/src/tracer.rs +++ b/runtime_tracing/src/tracer.rs @@ -107,6 +107,7 @@ pub struct Tracer { types: HashMap, format: TraceEventsFileFormat, + trace_events_path: PathBuf, } #[derive(Debug, Clone, Copy)] @@ -143,6 +144,7 @@ impl Tracer { types: HashMap::new(), format: TraceEventsFileFormat::Binary, + trace_events_path: PathBuf::new(), } } @@ -168,6 +170,7 @@ impl Tracer { impl TraceWriter for Tracer { fn begin_writing_trace_events(&mut self, path: &Path) -> Result<(), Box> { + self.trace_events_path = path.to_path_buf(); Ok(()) } From 594c90178d5862353d8980e407c135a0e6c52dd1 Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Tue, 15 Jul 2025 18:20:55 +0300 Subject: [PATCH 15/30] feat(stream_api): removed the format parameter from TraceWriter::store_trace_events(). Instead, use the format, specified in the previous call to begin_writing_trace_events() --- runtime_tracing/src/tracer.rs | 6 +++--- runtime_tracing_cli/src/main.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/runtime_tracing/src/tracer.rs b/runtime_tracing/src/tracer.rs index b3455ab..9fac62c 100644 --- a/runtime_tracing/src/tracer.rs +++ b/runtime_tracing/src/tracer.rs @@ -81,7 +81,7 @@ pub trait TraceWriter { fn append_events(&mut self, events: &mut Vec); fn store_trace_metadata(&self, path: &Path) -> Result<(), Box>; - fn store_trace_events(&self, path: &Path, format: TraceEventsFileFormat) -> Result<(), Box>; + fn store_trace_events(&self, path: &Path) -> Result<(), Box>; fn store_trace_paths(&self, path: &Path) -> Result<(), Box>; } @@ -408,8 +408,8 @@ impl TraceWriter for Tracer { Ok(()) } - fn store_trace_events(&self, path: &Path, format: TraceEventsFileFormat) -> Result<(), Box> { - match format { + fn store_trace_events(&self, path: &Path) -> Result<(), Box> { + match self.format { TraceEventsFileFormat::Json => { let json = serde_json::to_string(&self.events)?; fs::write(path, json)?; diff --git a/runtime_tracing_cli/src/main.rs b/runtime_tracing_cli/src/main.rs index 1537a30..16b0329 100644 --- a/runtime_tracing_cli/src/main.rs +++ b/runtime_tracing_cli/src/main.rs @@ -49,7 +49,7 @@ fn main() { let mut trace_events = trace_reader.load_trace_events(Path::new(&convert_command.input_file)).unwrap(); trace_writer.begin_writing_trace_events(Path::new(&convert_command.output_file)).unwrap(); trace_writer.append_events(&mut trace_events); - trace_writer.store_trace_events(Path::new(&convert_command.output_file), output_file_format).unwrap(); + trace_writer.store_trace_events(Path::new(&convert_command.output_file)).unwrap(); }, RuntimeTracingCliCommand::FormatTrace(fmt_trace_cmd) => { fmt_trace_cmd::run(fmt_trace_cmd); From ed68f5815f3c71658964c735d3df3b35e9edb758 Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Tue, 15 Jul 2025 18:24:50 +0300 Subject: [PATCH 16/30] feat(stream_api): removed the path parameter from TraceWriter::store_trace_events(). Use the path, specified in the previous call to begin_writing_trace_events() instead --- runtime_tracing/src/tracer.rs | 8 ++++---- runtime_tracing_cli/src/main.rs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/runtime_tracing/src/tracer.rs b/runtime_tracing/src/tracer.rs index 9fac62c..9ade692 100644 --- a/runtime_tracing/src/tracer.rs +++ b/runtime_tracing/src/tracer.rs @@ -81,7 +81,7 @@ pub trait TraceWriter { fn append_events(&mut self, events: &mut Vec); fn store_trace_metadata(&self, path: &Path) -> Result<(), Box>; - fn store_trace_events(&self, path: &Path) -> Result<(), Box>; + fn store_trace_events(&self) -> Result<(), Box>; fn store_trace_paths(&self, path: &Path) -> Result<(), Box>; } @@ -408,14 +408,14 @@ impl TraceWriter for Tracer { Ok(()) } - fn store_trace_events(&self, path: &Path) -> Result<(), Box> { + fn store_trace_events(&self) -> Result<(), Box> { match self.format { TraceEventsFileFormat::Json => { let json = serde_json::to_string(&self.events)?; - fs::write(path, json)?; + fs::write(self.trace_events_path.clone(), json)?; } TraceEventsFileFormat::Binary => { - let mut file = fs::File::create(path)?; + let mut file = fs::File::create(self.trace_events_path.clone())?; crate::capnptrace::write_trace(&self.events, &mut file)?; } } diff --git a/runtime_tracing_cli/src/main.rs b/runtime_tracing_cli/src/main.rs index 16b0329..c6127b2 100644 --- a/runtime_tracing_cli/src/main.rs +++ b/runtime_tracing_cli/src/main.rs @@ -49,7 +49,7 @@ fn main() { let mut trace_events = trace_reader.load_trace_events(Path::new(&convert_command.input_file)).unwrap(); trace_writer.begin_writing_trace_events(Path::new(&convert_command.output_file)).unwrap(); trace_writer.append_events(&mut trace_events); - trace_writer.store_trace_events(Path::new(&convert_command.output_file)).unwrap(); + trace_writer.store_trace_events().unwrap(); }, RuntimeTracingCliCommand::FormatTrace(fmt_trace_cmd) => { fmt_trace_cmd::run(fmt_trace_cmd); From 009d3dd5c1c0e7a7674db2f6578b52fde838cdbe Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Tue, 15 Jul 2025 18:25:52 +0300 Subject: [PATCH 17/30] feat(stream_api): removed unused 'use' --- runtime_tracing_cli/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime_tracing_cli/src/main.rs b/runtime_tracing_cli/src/main.rs index c6127b2..6531173 100644 --- a/runtime_tracing_cli/src/main.rs +++ b/runtime_tracing_cli/src/main.rs @@ -1,7 +1,7 @@ use std::path::Path; use clap::{Args, Parser, Subcommand}; -use runtime_tracing::{create_trace_reader, create_trace_writer, TraceEventsFileFormat, TraceWriter, Tracer}; +use runtime_tracing::{create_trace_reader, create_trace_writer, TraceEventsFileFormat}; use crate::fmt_trace_cmd::FmtTraceCommand; mod fmt_trace_cmd; From 7cdd9cdf0848a2da1982a649eb29b22db71697b8 Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Tue, 15 Jul 2025 18:28:12 +0300 Subject: [PATCH 18/30] feat(stream_api): store_trace_events() renamed finish_writing_trace_events() --- runtime_tracing/src/tracer.rs | 4 ++-- runtime_tracing_cli/src/main.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/runtime_tracing/src/tracer.rs b/runtime_tracing/src/tracer.rs index 9ade692..7f12f25 100644 --- a/runtime_tracing/src/tracer.rs +++ b/runtime_tracing/src/tracer.rs @@ -81,7 +81,7 @@ pub trait TraceWriter { fn append_events(&mut self, events: &mut Vec); fn store_trace_metadata(&self, path: &Path) -> Result<(), Box>; - fn store_trace_events(&self) -> Result<(), Box>; + fn finish_writing_trace_events(&self) -> Result<(), Box>; fn store_trace_paths(&self, path: &Path) -> Result<(), Box>; } @@ -408,7 +408,7 @@ impl TraceWriter for Tracer { Ok(()) } - fn store_trace_events(&self) -> Result<(), Box> { + fn finish_writing_trace_events(&self) -> Result<(), Box> { match self.format { TraceEventsFileFormat::Json => { let json = serde_json::to_string(&self.events)?; diff --git a/runtime_tracing_cli/src/main.rs b/runtime_tracing_cli/src/main.rs index 6531173..7e127a4 100644 --- a/runtime_tracing_cli/src/main.rs +++ b/runtime_tracing_cli/src/main.rs @@ -49,7 +49,7 @@ fn main() { let mut trace_events = trace_reader.load_trace_events(Path::new(&convert_command.input_file)).unwrap(); trace_writer.begin_writing_trace_events(Path::new(&convert_command.output_file)).unwrap(); trace_writer.append_events(&mut trace_events); - trace_writer.store_trace_events().unwrap(); + trace_writer.finish_writing_trace_events().unwrap(); }, RuntimeTracingCliCommand::FormatTrace(fmt_trace_cmd) => { fmt_trace_cmd::run(fmt_trace_cmd); From 100b5d72a1df8058c9374de5fc40baba424d3a17 Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Tue, 15 Jul 2025 18:37:05 +0300 Subject: [PATCH 19/30] feat(stream_api): update test test_binary_roundtrip to use the new API --- runtime_tracing/tests/binary_format.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/runtime_tracing/tests/binary_format.rs b/runtime_tracing/tests/binary_format.rs index 6be880e..b2f489f 100644 --- a/runtime_tracing/tests/binary_format.rs +++ b/runtime_tracing/tests/binary_format.rs @@ -1,4 +1,4 @@ -use runtime_tracing::{TraceEventsFileFormat, Tracer}; +use runtime_tracing::{create_trace_reader, create_trace_writer, TraceEventsFileFormat}; use std::path::Path; use std::fs; @@ -6,27 +6,27 @@ use std::fs; fn test_binary_roundtrip() { let json_path = Path::new("tests/data/trace.json"); - let mut tracer = Tracer::new("", &[]); - tracer - .load_trace_events(json_path, TraceEventsFileFormat::Json) + let mut json_reader = create_trace_reader(TraceEventsFileFormat::Json); + let original = json_reader + .load_trace_events(json_path) .unwrap(); - let original = tracer.events.clone(); let bin_path = Path::new("tests/data/trace.bin"); - tracer - .store_trace_events(bin_path, TraceEventsFileFormat::Binary) - .unwrap(); + let mut bin_writer = create_trace_writer("", &[], TraceEventsFileFormat::Binary); + bin_writer.begin_writing_trace_events(bin_path).unwrap(); + bin_writer.append_events(&mut original.clone()); + bin_writer.finish_writing_trace_events().unwrap(); - let mut tracer2 = Tracer::new("", &[]); - tracer2 - .load_trace_events(bin_path, TraceEventsFileFormat::Binary) + let mut bin_reader = create_trace_reader(TraceEventsFileFormat::Binary); + let tracer2_events = bin_reader + .load_trace_events(bin_path) .unwrap(); fs::remove_file(bin_path).unwrap(); let orig_json = serde_json::to_string(&original).unwrap(); - let new_json = serde_json::to_string(&tracer2.events).unwrap(); + let new_json = serde_json::to_string(&tracer2_events).unwrap(); assert_eq!(orig_json, new_json); } From 3cde38a272020f8acabd3b6112fa9c0fddf21b4c Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Tue, 15 Jul 2025 19:13:55 +0300 Subject: [PATCH 20/30] feat(stream_api): the Tracer struct was renamed NonStreamingTraceWriter --- runtime_tracing/src/lib.rs | 4 ++-- runtime_tracing/src/tracer.rs | 15 ++++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/runtime_tracing/src/lib.rs b/runtime_tracing/src/lib.rs index 4af9aeb..9dcfa73 100644 --- a/runtime_tracing/src/lib.rs +++ b/runtime_tracing/src/lib.rs @@ -12,7 +12,7 @@ mod tracer; mod types; mod base64; mod capnptrace; -pub use crate::tracer::{Tracer, TraceWriter, TraceEventsFileFormat, NONE_TYPE_ID, NONE_VALUE, create_trace_reader, create_trace_writer}; +pub use crate::tracer::{NonStreamingTraceWriter, TraceWriter, TraceEventsFileFormat, NONE_TYPE_ID, NONE_VALUE, create_trace_reader, create_trace_writer}; pub use crate::types::*; pub mod trace_capnp { @@ -27,7 +27,7 @@ mod tests { #[test] fn test_simple_trace() { - let mut tracer = Tracer::new("path.small", &vec![]); + let mut tracer = NonStreamingTraceWriter::new("path.small", &vec![]); let path = Path::new("/test/path.small"); tracer.start(path, Line(1)); tracer.register_step(path, Line(1)); diff --git a/runtime_tracing/src/tracer.rs b/runtime_tracing/src/tracer.rs index 7f12f25..a7c8c50 100644 --- a/runtime_tracing/src/tracer.rs +++ b/runtime_tracing/src/tracer.rs @@ -88,9 +88,10 @@ pub trait TraceWriter { /// State machine used to record [`TraceLowLevelEvent`]s. /// -/// A `Tracer` instance accumulates events and can store them on disk via the -/// `store_trace_*` methods. -pub struct Tracer { +/// A `NonStreamingTraceWriter` instance accumulates events in memory and stores them on +/// disk when the `finish_writing_trace_*` methods are called. The in-memory event list +/// is exposed publicly. +pub struct NonStreamingTraceWriter { // trace metadata: workdir: PathBuf, program: String, @@ -127,10 +128,10 @@ pub const NONE_VALUE: ValueRecord = ValueRecord::None { type_id: NONE_TYPE_ID }; pub const TOP_LEVEL_FUNCTION_ID: FunctionId = FunctionId(0); -impl Tracer { +impl NonStreamingTraceWriter { /// Create a new tracer instance for the given program and arguments. pub fn new(program: &str, args: &[String]) -> Self { - Tracer { + NonStreamingTraceWriter { workdir: env::current_dir().expect("can access the current dir"), program: program.to_string(), args: args.to_vec(), @@ -168,7 +169,7 @@ impl Tracer { } } -impl TraceWriter for Tracer { +impl TraceWriter for NonStreamingTraceWriter { fn begin_writing_trace_events(&mut self, path: &Path) -> Result<(), Box> { self.trace_events_path = path.to_path_buf(); Ok(()) @@ -442,7 +443,7 @@ pub fn create_trace_reader(format: TraceEventsFileFormat) -> Box Box { - let mut result = Box::new(Tracer::new(program, args)); + let mut result = Box::new(NonStreamingTraceWriter::new(program, args)); result.set_format(format); result } From b8cbbbe09c5ef5e31d0d875ebe4be0092d03f2d9 Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Tue, 15 Jul 2025 19:32:30 +0300 Subject: [PATCH 21/30] feat(stream_api): added check and panic, when finish_writing_trace_events is called without begin_writing_trace_events --- runtime_tracing/src/tracer.rs | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/runtime_tracing/src/tracer.rs b/runtime_tracing/src/tracer.rs index a7c8c50..0e840eb 100644 --- a/runtime_tracing/src/tracer.rs +++ b/runtime_tracing/src/tracer.rs @@ -108,7 +108,7 @@ pub struct NonStreamingTraceWriter { types: HashMap, format: TraceEventsFileFormat, - trace_events_path: PathBuf, + trace_events_path: Option, } #[derive(Debug, Clone, Copy)] @@ -145,7 +145,7 @@ impl NonStreamingTraceWriter { types: HashMap::new(), format: TraceEventsFileFormat::Binary, - trace_events_path: PathBuf::new(), + trace_events_path: None, } } @@ -171,7 +171,7 @@ impl NonStreamingTraceWriter { impl TraceWriter for NonStreamingTraceWriter { fn begin_writing_trace_events(&mut self, path: &Path) -> Result<(), Box> { - self.trace_events_path = path.to_path_buf(); + self.trace_events_path = Some(path.to_path_buf()); Ok(()) } @@ -410,17 +410,21 @@ impl TraceWriter for NonStreamingTraceWriter { } fn finish_writing_trace_events(&self) -> Result<(), Box> { - match self.format { - TraceEventsFileFormat::Json => { - let json = serde_json::to_string(&self.events)?; - fs::write(self.trace_events_path.clone(), json)?; - } - TraceEventsFileFormat::Binary => { - let mut file = fs::File::create(self.trace_events_path.clone())?; - crate::capnptrace::write_trace(&self.events, &mut file)?; + if let Some(path) = &self.trace_events_path { + match self.format { + TraceEventsFileFormat::Json => { + let json = serde_json::to_string(&self.events)?; + fs::write(path, json)?; + } + TraceEventsFileFormat::Binary => { + let mut file = fs::File::create(path)?; + crate::capnptrace::write_trace(&self.events, &mut file)?; + } } + Ok(()) + } else { + panic!("finish_writing_trace_events() called without previous call to begin_writing_trace_events()"); } - Ok(()) } fn store_trace_paths(&self, path: &Path) -> Result<(), Box> { From 6a21f9599acc1af3c67190d1ba246ab634793777 Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Tue, 15 Jul 2025 19:39:06 +0300 Subject: [PATCH 22/30] feat(stream_api): introduced begin_writing_trace_metadata and begin_writing_trace_paths --- runtime_tracing/src/tracer.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/runtime_tracing/src/tracer.rs b/runtime_tracing/src/tracer.rs index 0e840eb..d941a29 100644 --- a/runtime_tracing/src/tracer.rs +++ b/runtime_tracing/src/tracer.rs @@ -40,7 +40,9 @@ impl TraceReader for BinaryTraceReader { } pub trait TraceWriter { + fn begin_writing_trace_metadata(&mut self, path: &Path) -> Result<(), Box>; fn begin_writing_trace_events(&mut self, path: &Path) -> Result<(), Box>; + fn begin_writing_trace_paths(&mut self, path: &Path) -> Result<(), Box>; fn start(&mut self, path: &Path, line: Line); fn ensure_path_id(&mut self, path: &Path) -> PathId; @@ -108,7 +110,9 @@ pub struct NonStreamingTraceWriter { types: HashMap, format: TraceEventsFileFormat, + trace_metadata_path: Option, trace_events_path: Option, + trace_paths_path: Option, } #[derive(Debug, Clone, Copy)] @@ -145,7 +149,9 @@ impl NonStreamingTraceWriter { types: HashMap::new(), format: TraceEventsFileFormat::Binary, + trace_metadata_path: None, trace_events_path: None, + trace_paths_path: None, } } @@ -170,11 +176,21 @@ impl NonStreamingTraceWriter { } impl TraceWriter for NonStreamingTraceWriter { + fn begin_writing_trace_metadata(&mut self, path: &Path) -> Result<(), Box> { + self.trace_metadata_path = Some(path.to_path_buf()); + Ok(()) + } + fn begin_writing_trace_events(&mut self, path: &Path) -> Result<(), Box> { self.trace_events_path = Some(path.to_path_buf()); Ok(()) } + fn begin_writing_trace_paths(&mut self, path: &Path) -> Result<(), Box> { + self.trace_paths_path = Some(path.to_path_buf()); + Ok(()) + } + /// Begin tracing of a program starting at the given source location. fn start(&mut self, path: &Path, line: Line) { let function_id = self.ensure_function_id("", path, line); From 9d8f0464e20556f9bf9c5d589b6e58221d8e4442 Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Tue, 15 Jul 2025 19:40:37 +0300 Subject: [PATCH 23/30] feat(stream_api): method store_trace_metadata renamed finish_writing_trace_metadata --- runtime_tracing/src/tracer.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime_tracing/src/tracer.rs b/runtime_tracing/src/tracer.rs index d941a29..125d1ee 100644 --- a/runtime_tracing/src/tracer.rs +++ b/runtime_tracing/src/tracer.rs @@ -82,7 +82,7 @@ pub trait TraceWriter { fn add_event(&mut self, event: TraceLowLevelEvent); fn append_events(&mut self, events: &mut Vec); - fn store_trace_metadata(&self, path: &Path) -> Result<(), Box>; + fn finish_writing_trace_metadata(&self, path: &Path) -> Result<(), Box>; fn finish_writing_trace_events(&self) -> Result<(), Box>; fn store_trace_paths(&self, path: &Path) -> Result<(), Box>; } @@ -414,7 +414,7 @@ impl TraceWriter for NonStreamingTraceWriter { self.events.append(events); } - fn store_trace_metadata(&self, path: &Path) -> Result<(), Box> { + fn finish_writing_trace_metadata(&self, path: &Path) -> Result<(), Box> { let trace_metadata = TraceMetadata { program: self.program.clone(), args: self.args.clone(), From 775817a9374d307c6b6b7a738bc91527b0e730f8 Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Tue, 15 Jul 2025 19:41:07 +0300 Subject: [PATCH 24/30] feat(stream_api): method store_trace_paths renamed finish_writing_trace_paths --- runtime_tracing/src/tracer.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime_tracing/src/tracer.rs b/runtime_tracing/src/tracer.rs index 125d1ee..0ff258f 100644 --- a/runtime_tracing/src/tracer.rs +++ b/runtime_tracing/src/tracer.rs @@ -84,7 +84,7 @@ pub trait TraceWriter { fn finish_writing_trace_metadata(&self, path: &Path) -> Result<(), Box>; fn finish_writing_trace_events(&self) -> Result<(), Box>; - fn store_trace_paths(&self, path: &Path) -> Result<(), Box>; + fn finish_writing_trace_paths(&self, path: &Path) -> Result<(), Box>; } @@ -443,7 +443,7 @@ impl TraceWriter for NonStreamingTraceWriter { } } - fn store_trace_paths(&self, path: &Path) -> Result<(), Box> { + fn finish_writing_trace_paths(&self, path: &Path) -> Result<(), Box> { let json = serde_json::to_string(&self.path_list)?; fs::write(path, json)?; Ok(()) From da7cff15ca521dc3edd3ca9b2e2dee676666d1fd Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Tue, 15 Jul 2025 19:43:57 +0300 Subject: [PATCH 25/30] feat(stream_api): removed the parameter path from finish_writing_trace_metadata; use the path, specified in the call to begin_writing_trace_metadata --- runtime_tracing/src/tracer.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/runtime_tracing/src/tracer.rs b/runtime_tracing/src/tracer.rs index 0ff258f..a0d9858 100644 --- a/runtime_tracing/src/tracer.rs +++ b/runtime_tracing/src/tracer.rs @@ -82,7 +82,7 @@ pub trait TraceWriter { fn add_event(&mut self, event: TraceLowLevelEvent); fn append_events(&mut self, events: &mut Vec); - fn finish_writing_trace_metadata(&self, path: &Path) -> Result<(), Box>; + fn finish_writing_trace_metadata(&self) -> Result<(), Box>; fn finish_writing_trace_events(&self) -> Result<(), Box>; fn finish_writing_trace_paths(&self, path: &Path) -> Result<(), Box>; } @@ -414,15 +414,19 @@ impl TraceWriter for NonStreamingTraceWriter { self.events.append(events); } - fn finish_writing_trace_metadata(&self, path: &Path) -> Result<(), Box> { - let trace_metadata = TraceMetadata { - program: self.program.clone(), - args: self.args.clone(), - workdir: self.workdir.clone(), - }; - let json = serde_json::to_string(&trace_metadata)?; - fs::write(path, json)?; - Ok(()) + fn finish_writing_trace_metadata(&self) -> Result<(), Box> { + if let Some(path) = &self.trace_metadata_path { + let trace_metadata = TraceMetadata { + program: self.program.clone(), + args: self.args.clone(), + workdir: self.workdir.clone(), + }; + let json = serde_json::to_string(&trace_metadata)?; + fs::write(path, json)?; + Ok(()) + } else { + panic!("finish_writing_trace_metadata() called without previous call to begin_writing_trace_metadata()"); + } } fn finish_writing_trace_events(&self) -> Result<(), Box> { From b1440f22903ced73c7b4b19dffd60b081909820e Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Tue, 15 Jul 2025 19:45:21 +0300 Subject: [PATCH 26/30] feat(stream_api): removed the parameter path from finish_writing_trace_paths; use the path, specified in the call to begin_writing_trace_paths --- runtime_tracing/src/tracer.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/runtime_tracing/src/tracer.rs b/runtime_tracing/src/tracer.rs index a0d9858..a443d36 100644 --- a/runtime_tracing/src/tracer.rs +++ b/runtime_tracing/src/tracer.rs @@ -84,7 +84,7 @@ pub trait TraceWriter { fn finish_writing_trace_metadata(&self) -> Result<(), Box>; fn finish_writing_trace_events(&self) -> Result<(), Box>; - fn finish_writing_trace_paths(&self, path: &Path) -> Result<(), Box>; + fn finish_writing_trace_paths(&self) -> Result<(), Box>; } @@ -447,10 +447,14 @@ impl TraceWriter for NonStreamingTraceWriter { } } - fn finish_writing_trace_paths(&self, path: &Path) -> Result<(), Box> { - let json = serde_json::to_string(&self.path_list)?; - fs::write(path, json)?; - Ok(()) + fn finish_writing_trace_paths(&self) -> Result<(), Box> { + if let Some(path) = &self.trace_paths_path { + let json = serde_json::to_string(&self.path_list)?; + fs::write(path, json)?; + Ok(()) + } else { + panic!("finish_writing_trace_paths() called without previous call to begin_writing_trace_paths()"); + } } } From 141001cc367ed096365ffff385c13f3a9af96b41 Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Tue, 15 Jul 2025 19:47:53 +0300 Subject: [PATCH 27/30] feat(stream_api): methods finish_writing_trace_* now take a mutable self reference --- runtime_tracing/src/tracer.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/runtime_tracing/src/tracer.rs b/runtime_tracing/src/tracer.rs index a443d36..556c025 100644 --- a/runtime_tracing/src/tracer.rs +++ b/runtime_tracing/src/tracer.rs @@ -82,9 +82,9 @@ pub trait TraceWriter { fn add_event(&mut self, event: TraceLowLevelEvent); fn append_events(&mut self, events: &mut Vec); - fn finish_writing_trace_metadata(&self) -> Result<(), Box>; - fn finish_writing_trace_events(&self) -> Result<(), Box>; - fn finish_writing_trace_paths(&self) -> Result<(), Box>; + fn finish_writing_trace_metadata(&mut self) -> Result<(), Box>; + fn finish_writing_trace_events(&mut self) -> Result<(), Box>; + fn finish_writing_trace_paths(&mut self) -> Result<(), Box>; } @@ -414,7 +414,7 @@ impl TraceWriter for NonStreamingTraceWriter { self.events.append(events); } - fn finish_writing_trace_metadata(&self) -> Result<(), Box> { + fn finish_writing_trace_metadata(&mut self) -> Result<(), Box> { if let Some(path) = &self.trace_metadata_path { let trace_metadata = TraceMetadata { program: self.program.clone(), @@ -429,7 +429,7 @@ impl TraceWriter for NonStreamingTraceWriter { } } - fn finish_writing_trace_events(&self) -> Result<(), Box> { + fn finish_writing_trace_events(&mut self) -> Result<(), Box> { if let Some(path) = &self.trace_events_path { match self.format { TraceEventsFileFormat::Json => { @@ -447,7 +447,7 @@ impl TraceWriter for NonStreamingTraceWriter { } } - fn finish_writing_trace_paths(&self) -> Result<(), Box> { + fn finish_writing_trace_paths(&mut self) -> Result<(), Box> { if let Some(path) = &self.trace_paths_path { let json = serde_json::to_string(&self.path_list)?; fs::write(path, json)?; From 64074a2799be9293594e50ba12d3643ce74c60be Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Tue, 15 Jul 2025 19:57:42 +0300 Subject: [PATCH 28/30] feat(stream_api): also reexport the TraceReader trait --- runtime_tracing/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime_tracing/src/lib.rs b/runtime_tracing/src/lib.rs index 9dcfa73..cc87ccd 100644 --- a/runtime_tracing/src/lib.rs +++ b/runtime_tracing/src/lib.rs @@ -12,7 +12,7 @@ mod tracer; mod types; mod base64; mod capnptrace; -pub use crate::tracer::{NonStreamingTraceWriter, TraceWriter, TraceEventsFileFormat, NONE_TYPE_ID, NONE_VALUE, create_trace_reader, create_trace_writer}; +pub use crate::tracer::{TraceReader, NonStreamingTraceWriter, TraceWriter, TraceEventsFileFormat, NONE_TYPE_ID, NONE_VALUE, create_trace_reader, create_trace_writer}; pub use crate::types::*; pub mod trace_capnp { From 43988227f0669930b6485ed77adb6332031feab1 Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Tue, 15 Jul 2025 19:58:31 +0300 Subject: [PATCH 29/30] chore: cargo fmt --- runtime_tracing/build.rs | 5 +- runtime_tracing/src/base64.rs | 4 +- runtime_tracing/src/capnptrace.rs | 238 +++++++------------------ runtime_tracing/src/lib.rs | 8 +- runtime_tracing/src/tracer.rs | 18 +- runtime_tracing/src/types.rs | 4 +- runtime_tracing/tests/binary_format.rs | 10 +- runtime_tracing_cli/src/main.rs | 4 +- trace_formatter/src/read_write_json.rs | 7 +- 9 files changed, 92 insertions(+), 206 deletions(-) diff --git a/runtime_tracing/build.rs b/runtime_tracing/build.rs index e51548f..f139dff 100644 --- a/runtime_tracing/build.rs +++ b/runtime_tracing/build.rs @@ -1,6 +1,3 @@ fn main() { - ::capnpc::CompilerCommand::new() - .file("src/trace.capnp") - .run() - .expect("compiling schema") + ::capnpc::CompilerCommand::new().file("src/trace.capnp").run().expect("compiling schema") } diff --git a/runtime_tracing/src/base64.rs b/runtime_tracing/src/base64.rs index a38e8f9..c451918 100644 --- a/runtime_tracing/src/base64.rs +++ b/runtime_tracing/src/base64.rs @@ -9,5 +9,7 @@ pub fn serialize(v: &Vec, s: S) -> Result { pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result, D::Error> { let base64 = String::deserialize(d)?; - base64::engine::general_purpose::STANDARD.decode(base64.as_bytes()).map_err(serde::de::Error::custom) + base64::engine::general_purpose::STANDARD + .decode(base64.as_bytes()) + .map_err(serde::de::Error::custom) } diff --git a/runtime_tracing/src/capnptrace.rs b/runtime_tracing/src/capnptrace.rs index 4d1a5af..7b3a4aa 100644 --- a/runtime_tracing/src/capnptrace.rs +++ b/runtime_tracing/src/capnptrace.rs @@ -1,7 +1,7 @@ -use std::str::FromStr; use crate::trace_capnp::trace; -use capnp::serialize_packed; use crate::{TraceLowLevelEvent, VariableId}; +use capnp::serialize_packed; +use std::str::FromStr; /// The first 5 bytes identify the file as a CodeTracer file (hex l33tsp33k - C0DE72ACE2 for "CodeTracer"). /// The next 3 bytes are reserved/version info. In the initial version, they are zero. Non-zero values might @@ -142,11 +142,7 @@ impl From for trace::PassBy { } } - -fn conv_valuerecord( - bldr: crate::trace_capnp::trace::value_record::Builder, - vr: &crate::ValueRecord, -) { +fn conv_valuerecord(bldr: crate::trace_capnp::trace::value_record::Builder, vr: &crate::ValueRecord) { match vr { crate::ValueRecord::Int { i, type_id } => { let mut qi = bldr.init_int(); @@ -172,15 +168,9 @@ fn conv_valuerecord( let mut q_typ_id = qs.init_type_id(); q_typ_id.set_i(type_id.0.try_into().unwrap()); } - crate::ValueRecord::Sequence { - elements, - is_slice, - type_id, - } => { + crate::ValueRecord::Sequence { elements, is_slice, type_id } => { let mut qseq = bldr.init_sequence(); - let mut elems = qseq - .reborrow() - .init_elements(elements.len().try_into().unwrap()); + let mut elems = qseq.reborrow().init_elements(elements.len().try_into().unwrap()); for i in 0..elements.len() { let ele = &elements[i]; let bele = elems.reborrow().get(i.try_into().unwrap()); @@ -192,9 +182,7 @@ fn conv_valuerecord( } crate::ValueRecord::Tuple { elements, type_id } => { let mut qtup = bldr.init_tuple(); - let mut elems = qtup - .reborrow() - .init_elements(elements.len().try_into().unwrap()); + let mut elems = qtup.reborrow().init_elements(elements.len().try_into().unwrap()); for i in 0..elements.len() { let ele = &elements[i]; let bele = elems.reborrow().get(i.try_into().unwrap()); @@ -203,14 +191,9 @@ fn conv_valuerecord( let mut q_typ_id = qtup.init_type_id(); q_typ_id.set_i(type_id.0.try_into().unwrap()); } - crate::ValueRecord::Struct { - field_values, - type_id, - } => { + crate::ValueRecord::Struct { field_values, type_id } => { let mut qstruc = bldr.init_struct(); - let mut elems = qstruc - .reborrow() - .init_field_values(field_values.len().try_into().unwrap()); + let mut elems = qstruc.reborrow().init_field_values(field_values.len().try_into().unwrap()); for i in 0..field_values.len() { let ele = &field_values[i]; let bele = elems.reborrow().get(i.try_into().unwrap()); @@ -311,9 +294,7 @@ pub fn write_trace(q: &[crate::TraceLowLevelEvent], output: &mut impl std::io::W typ_id.set_i(ftr.type_id.0.try_into().unwrap()); } } - crate::TypeSpecificInfo::Pointer { - dereference_type_id, - } => { + crate::TypeSpecificInfo::Pointer { dereference_type_id } => { let ptr = specific_info.init_pointer(); let mut deref_typ_id = ptr.init_dereference_type_id(); deref_typ_id.set_i(dereference_type_id.0.try_into().unwrap()); @@ -336,8 +317,7 @@ pub fn write_trace(q: &[crate::TraceLowLevelEvent], output: &mut impl std::io::W let mut call_record = event.init_call(); let mut function_id = call_record.reborrow().init_function_id(); function_id.set_i(callrecord.function_id.0.try_into().unwrap()); - let mut function_args = - call_record.init_args(callrecord.args.len().try_into().unwrap()); + let mut function_args = call_record.init_args(callrecord.args.len().try_into().unwrap()); for i in 0..callrecord.args.len() { let farg = &callrecord.args[i]; let mut arg = function_args.reborrow().get(i.try_into().unwrap()); @@ -401,14 +381,14 @@ pub fn write_trace(q: &[crate::TraceLowLevelEvent], output: &mut impl std::io::W crate::RValue::Simple(variable_id) => { let mut ret_from_simple = ret_from.init_simple(); ret_from_simple.set_i(variable_id.0.try_into().unwrap()); - }, + } crate::RValue::Compound(variable_ids) => { let mut ret_from_compound = ret_from.init_compound(variable_ids.len().try_into().unwrap()); for i in 0..variable_ids.len() { let mut r = ret_from_compound.reborrow().get(i.try_into().unwrap()); r.set_i(variable_ids[i].0.try_into().unwrap()); } - }, + } } } TraceLowLevelEvent::DropLastStep => { @@ -469,20 +449,15 @@ pub fn write_trace(q: &[crate::TraceLowLevelEvent], output: &mut impl std::io::W serialize_packed::write_message(output, &message) } -fn get_value_records( - r: capnp::struct_list::Reader, -) -> Result, capnp::Error> { - let mut res: Vec = - Vec::with_capacity(r.len().try_into().unwrap()); +fn get_value_records(r: capnp::struct_list::Reader) -> Result, capnp::Error> { + let mut res: Vec = Vec::with_capacity(r.len().try_into().unwrap()); for i in 0..r.len() { res.push(get_value_record(r.get(i))?); } Ok(res) } -fn get_value_record( - r: trace::value_record::Reader, -) -> Result { +fn get_value_record(r: trace::value_record::Reader) -> Result { match r.which() { Ok(trace::value_record::Which::Int(q)) => Ok(crate::ValueRecord::Int { i: q.get_i(), @@ -500,13 +475,11 @@ fn get_value_record( text: q.get_text()?.to_string()?, type_id: crate::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), }), - Ok(trace::value_record::Which::Sequence(q)) => { - Ok(crate::ValueRecord::Sequence { - elements: get_value_records(q.get_elements()?)?, - is_slice: q.get_is_slice(), - type_id: crate::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), - }) - } + Ok(trace::value_record::Which::Sequence(q)) => Ok(crate::ValueRecord::Sequence { + elements: get_value_records(q.get_elements()?)?, + is_slice: q.get_is_slice(), + type_id: crate::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), + }), Ok(trace::value_record::Which::Tuple(q)) => Ok(crate::ValueRecord::Tuple { elements: get_value_records(q.get_elements()?)?, type_id: crate::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), @@ -515,21 +488,17 @@ fn get_value_record( field_values: get_value_records(q.get_field_values()?)?, type_id: crate::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), }), - Ok(trace::value_record::Which::Variant(q)) => { - Ok(crate::ValueRecord::Variant { - discriminator: q.get_discriminator()?.to_string()?, - contents: Box::new(get_value_record(q.get_contents()?)?), - type_id: crate::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), - }) - } - Ok(trace::value_record::Which::Reference(q)) => { - Ok(crate::ValueRecord::Reference { - dereferenced: Box::new(get_value_record(q.get_dereferenced()?)?), - address: q.get_address(), - mutable: q.get_mutable(), - type_id: crate::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), - }) - } + Ok(trace::value_record::Which::Variant(q)) => Ok(crate::ValueRecord::Variant { + discriminator: q.get_discriminator()?.to_string()?, + contents: Box::new(get_value_record(q.get_contents()?)?), + type_id: crate::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), + }), + Ok(trace::value_record::Which::Reference(q)) => Ok(crate::ValueRecord::Reference { + dereferenced: Box::new(get_value_record(q.get_dereferenced()?)?), + address: q.get_address(), + mutable: q.get_mutable(), + type_id: crate::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), + }), Ok(trace::value_record::Which::Raw(q)) => Ok(crate::ValueRecord::Raw { r: q.get_r()?.to_string()?, type_id: crate::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), @@ -553,13 +522,9 @@ fn get_value_record( } } -fn get_full_value_record( - r: trace::full_value_record::Reader, -) -> Result { +fn get_full_value_record(r: trace::full_value_record::Reader) -> Result { Ok(crate::FullValueRecord { - variable_id: crate::VariableId( - r.get_variable_id()?.get_i().try_into().unwrap(), - ), + variable_id: crate::VariableId(r.get_variable_id()?.get_i().try_into().unwrap()), value: get_value_record(r.get_value()?)?, }) } @@ -570,83 +535,58 @@ pub fn read_trace(input: &mut impl std::io::BufRead) -> ::capnp::Result()?; - let mut res: Vec = - Vec::with_capacity(trace.get_events()?.len().try_into().unwrap()); + let mut res: Vec = Vec::with_capacity(trace.get_events()?.len().try_into().unwrap()); for event in trace.get_events()? { let q = match event.which() { Ok(trace::trace_low_level_event::Which::Step(step_record)) => { let step_record = step_record?; TraceLowLevelEvent::Step(crate::StepRecord { - path_id: crate::PathId( - step_record.get_path_id()?.get_i().try_into().unwrap(), - ), + path_id: crate::PathId(step_record.get_path_id()?.get_i().try_into().unwrap()), line: crate::Line(step_record.get_line()?.get_l()), }) } Ok(trace::trace_low_level_event::Which::Path(path_buf)) => { - TraceLowLevelEvent::Path( - std::path::PathBuf::from_str(path_buf?.get_p()?.to_str()?).unwrap(), - ) - } - Ok(trace::trace_low_level_event::Which::VariableName(variable_name)) => { - TraceLowLevelEvent::VariableName(variable_name?.to_string()?) - } - Ok(trace::trace_low_level_event::Which::Variable(variable)) => { - TraceLowLevelEvent::Variable(variable?.to_string()?) + TraceLowLevelEvent::Path(std::path::PathBuf::from_str(path_buf?.get_p()?.to_str()?).unwrap()) } + Ok(trace::trace_low_level_event::Which::VariableName(variable_name)) => TraceLowLevelEvent::VariableName(variable_name?.to_string()?), + Ok(trace::trace_low_level_event::Which::Variable(variable)) => TraceLowLevelEvent::Variable(variable?.to_string()?), Ok(trace::trace_low_level_event::Which::Type(type_record)) => { let type_record = type_record?; TraceLowLevelEvent::Type(crate::TypeRecord { kind: type_record.get_kind()?.into(), lang_type: type_record.get_lang_type()?.to_string()?, specific_info: match type_record.get_specific_info()?.which() { - Ok(trace::type_specific_info::Which::None(())) => { - crate::TypeSpecificInfo::None - } + Ok(trace::type_specific_info::Which::None(())) => crate::TypeSpecificInfo::None, Ok(trace::type_specific_info::Which::Struct(s)) => { let s_fields = s.get_fields()?; - let mut fields: Vec = - Vec::with_capacity(s_fields.len().try_into().unwrap()); + let mut fields: Vec = Vec::with_capacity(s_fields.len().try_into().unwrap()); for s_field in s_fields { fields.push(crate::FieldTypeRecord { name: s_field.get_name()?.to_string()?, - type_id: crate::TypeId( - s_field.get_type_id()?.get_i().try_into().unwrap(), - ), + type_id: crate::TypeId(s_field.get_type_id()?.get_i().try_into().unwrap()), }); } crate::TypeSpecificInfo::Struct { fields } } - Ok(trace::type_specific_info::Which::Pointer(p)) => { - crate::TypeSpecificInfo::Pointer { - dereference_type_id: crate::TypeId( - p.get_dereference_type_id()?.get_i().try_into().unwrap(), - ), - } - } + Ok(trace::type_specific_info::Which::Pointer(p)) => crate::TypeSpecificInfo::Pointer { + dereference_type_id: crate::TypeId(p.get_dereference_type_id()?.get_i().try_into().unwrap()), + }, Err(_) => { panic!() } }, }) } - Ok(trace::trace_low_level_event::Which::Value(fvr)) => { - TraceLowLevelEvent::Value(get_full_value_record(fvr?)?) - } + Ok(trace::trace_low_level_event::Which::Value(fvr)) => TraceLowLevelEvent::Value(get_full_value_record(fvr?)?), Ok(trace::trace_low_level_event::Which::Function(function_record)) => { let function_record = function_record?; TraceLowLevelEvent::Function(crate::FunctionRecord { - path_id: crate::PathId( - function_record.get_path_id()?.get_i().try_into().unwrap(), - ), + path_id: crate::PathId(function_record.get_path_id()?.get_i().try_into().unwrap()), line: crate::Line(function_record.get_line()?.get_l()), name: function_record.get_name()?.to_string()?, }) @@ -654,28 +594,21 @@ pub fn read_trace(input: &mut impl std::io::BufRead) -> ::capnp::Result { let call_record = call_record?; let sargs = call_record.get_args()?; - let mut args: Vec = - Vec::with_capacity(sargs.len().try_into().unwrap()); + let mut args: Vec = Vec::with_capacity(sargs.len().try_into().unwrap()); for sarg in sargs { args.push(crate::FullValueRecord { - variable_id: crate::VariableId( - sarg.get_variable_id()?.get_i().try_into().unwrap(), - ), + variable_id: crate::VariableId(sarg.get_variable_id()?.get_i().try_into().unwrap()), value: get_value_record(sarg.get_value()?)?, }); } TraceLowLevelEvent::Call(crate::CallRecord { - function_id: crate::FunctionId( - call_record.get_function_id()?.get_i().try_into().unwrap(), - ), + function_id: crate::FunctionId(call_record.get_function_id()?.get_i().try_into().unwrap()), args, }) } - Ok(trace::trace_low_level_event::Which::Return(return_record)) => { - TraceLowLevelEvent::Return(crate::ReturnRecord { - return_value: get_value_record(return_record?.get_return_value()?)?, - }) - } + Ok(trace::trace_low_level_event::Which::Return(return_record)) => TraceLowLevelEvent::Return(crate::ReturnRecord { + return_value: get_value_record(return_record?.get_return_value()?)?, + }), Ok(trace::trace_low_level_event::Which::Event(record_event)) => { let record_event = record_event?; TraceLowLevelEvent::Event(crate::RecordEvent { @@ -686,8 +619,7 @@ pub fn read_trace(input: &mut impl std::io::BufRead) -> ::capnp::Result { let asm_strings = asm_strings?; - let mut strs: Vec = - Vec::with_capacity(asm_strings.len().try_into().unwrap()); + let mut strs: Vec = Vec::with_capacity(asm_strings.len().try_into().unwrap()); for s in asm_strings { strs.push(s?.to_string()?); } @@ -696,40 +628,27 @@ pub fn read_trace(input: &mut impl std::io::BufRead) -> ::capnp::Result { let bind_variable_record = bind_variable_record?; TraceLowLevelEvent::BindVariable(crate::BindVariableRecord { - variable_id: crate::VariableId( - bind_variable_record - .get_variable_id()? - .get_i() - .try_into() - .unwrap(), - ), + variable_id: crate::VariableId(bind_variable_record.get_variable_id()?.get_i().try_into().unwrap()), place: crate::Place(bind_variable_record.get_place()?.get_p()), }) } Ok(trace::trace_low_level_event::Which::Assignment(assignment_record)) => { let assignment_record = assignment_record?; TraceLowLevelEvent::Assignment(crate::AssignmentRecord { - to: crate::VariableId( - assignment_record.get_to()?.get_i().try_into().unwrap(), - ), + to: crate::VariableId(assignment_record.get_to()?.get_i().try_into().unwrap()), pass_by: match assignment_record.get_pass_by()? { trace::PassBy::Value => crate::PassBy::Value, trace::PassBy::Reference => crate::PassBy::Reference, }, from: match assignment_record.get_from()?.which()? { trace::r_value::Which::Simple(variable_id) => { - crate::RValue::Simple(crate::VariableId( - variable_id?.get_i().try_into().unwrap(), - )) + crate::RValue::Simple(crate::VariableId(variable_id?.get_i().try_into().unwrap())) } trace::r_value::Which::Compound(variables) => { let variables = variables?; - let mut v: Vec = - Vec::with_capacity(variables.len().try_into().unwrap()); + let mut v: Vec = Vec::with_capacity(variables.len().try_into().unwrap()); for vv in variables { - v.push(crate::VariableId( - vv.get_i().try_into().unwrap(), - )); + v.push(crate::VariableId(vv.get_i().try_into().unwrap())); } crate::RValue::Compound(v) } @@ -738,8 +657,7 @@ pub fn read_trace(input: &mut impl std::io::BufRead) -> ::capnp::Result { let variables = variables?; - let mut v: Vec = - Vec::with_capacity(variables.len().try_into().unwrap()); + let mut v: Vec = Vec::with_capacity(variables.len().try_into().unwrap()); for vv in variables { v.push(crate::VariableId(vv.get_i().try_into().unwrap())) } @@ -759,21 +677,13 @@ pub fn read_trace(input: &mut impl std::io::BufRead) -> ::capnp::Result { + Ok(trace::trace_low_level_event::Which::AssignCompoundItem(assign_compound_item_record)) => { let assign_compound_item_record = assign_compound_item_record?; - TraceLowLevelEvent::AssignCompoundItem( - crate::AssignCompoundItemRecord { - place: crate::Place( - assign_compound_item_record.get_place()?.get_p(), - ), - index: assign_compound_item_record.get_index().try_into().unwrap(), - item_place: crate::Place( - assign_compound_item_record.get_item_place()?.get_p(), - ), - }, - ) + TraceLowLevelEvent::AssignCompoundItem(crate::AssignCompoundItemRecord { + place: crate::Place(assign_compound_item_record.get_place()?.get_p()), + index: assign_compound_item_record.get_index().try_into().unwrap(), + item_place: crate::Place(assign_compound_item_record.get_item_place()?.get_p()), + }) } Ok(trace::trace_low_level_event::Which::AssignCell(assign_cell_record)) => { let assign_cell_record = assign_cell_record?; @@ -785,24 +695,14 @@ pub fn read_trace(input: &mut impl std::io::BufRead) -> ::capnp::Result { let variable_cell_record = variable_cell_record?; TraceLowLevelEvent::VariableCell(crate::VariableCellRecord { - variable_id: crate::VariableId( - variable_cell_record - .get_variable_id()? - .get_i() - .try_into() - .unwrap(), - ), + variable_id: crate::VariableId(variable_cell_record.get_variable_id()?.get_i().try_into().unwrap()), place: crate::Place(variable_cell_record.get_place()?.get_p()), }) } Ok(trace::trace_low_level_event::Which::DropVariable(variable_id)) => { - TraceLowLevelEvent::DropVariable(crate::VariableId( - variable_id?.get_i().try_into().unwrap(), - )) - } - Ok(trace::trace_low_level_event::Which::DropLastStep(())) => { - TraceLowLevelEvent::DropLastStep + TraceLowLevelEvent::DropVariable(crate::VariableId(variable_id?.get_i().try_into().unwrap())) } + Ok(trace::trace_low_level_event::Which::DropLastStep(())) => TraceLowLevelEvent::DropLastStep, Err(_) => { panic!() } diff --git a/runtime_tracing/src/lib.rs b/runtime_tracing/src/lib.rs index cc87ccd..b9393de 100644 --- a/runtime_tracing/src/lib.rs +++ b/runtime_tracing/src/lib.rs @@ -8,11 +8,13 @@ //! This crate provides the [`Tracer`] type for emitting trace events and a //! collection of serializable structures describing the trace format. //! The format is documented in `docs/` and the README. -mod tracer; -mod types; mod base64; mod capnptrace; -pub use crate::tracer::{TraceReader, NonStreamingTraceWriter, TraceWriter, TraceEventsFileFormat, NONE_TYPE_ID, NONE_VALUE, create_trace_reader, create_trace_writer}; +mod tracer; +mod types; +pub use crate::tracer::{ + create_trace_reader, create_trace_writer, NonStreamingTraceWriter, TraceEventsFileFormat, TraceReader, TraceWriter, NONE_TYPE_ID, NONE_VALUE, +}; pub use crate::types::*; pub mod trace_capnp { diff --git a/runtime_tracing/src/tracer.rs b/runtime_tracing/src/tracer.rs index 556c025..e384947 100644 --- a/runtime_tracing/src/tracer.rs +++ b/runtime_tracing/src/tracer.rs @@ -18,8 +18,7 @@ pub trait TraceReader { fn load_trace_events(&mut self, path: &Path) -> Result, Box>; } -pub struct JsonTraceReader { -} +pub struct JsonTraceReader {} impl TraceReader for JsonTraceReader { fn load_trace_events(&mut self, path: &Path) -> Result, Box> { @@ -28,8 +27,7 @@ impl TraceReader for JsonTraceReader { } } -pub struct BinaryTraceReader { -} +pub struct BinaryTraceReader {} impl TraceReader for BinaryTraceReader { fn load_trace_events(&mut self, path: &Path) -> Result, Box> { @@ -87,7 +85,6 @@ pub trait TraceWriter { fn finish_writing_trace_paths(&mut self) -> Result<(), Box>; } - /// State machine used to record [`TraceLowLevelEvent`]s. /// /// A `NonStreamingTraceWriter` instance accumulates events in memory and stores them on @@ -118,7 +115,7 @@ pub struct NonStreamingTraceWriter { #[derive(Debug, Clone, Copy)] pub enum TraceEventsFileFormat { Json, - Binary + Binary, } // we ensure in start they are registered with those id-s @@ -460,14 +457,9 @@ impl TraceWriter for NonStreamingTraceWriter { pub fn create_trace_reader(format: TraceEventsFileFormat) -> Box { match format { - TraceEventsFileFormat::Json => { - Box::new(JsonTraceReader { } ) - } - TraceEventsFileFormat::Binary => { - Box::new(BinaryTraceReader { } ) - } + TraceEventsFileFormat::Json => Box::new(JsonTraceReader {}), + TraceEventsFileFormat::Binary => Box::new(BinaryTraceReader {}), } - } pub fn create_trace_writer(program: &str, args: &[String], format: TraceEventsFileFormat) -> Box { diff --git a/runtime_tracing/src/types.rs b/runtime_tracing/src/types.rs index c7988f7..2b33788 100644 --- a/runtime_tracing/src/types.rs +++ b/runtime_tracing/src/types.rs @@ -6,10 +6,10 @@ use std::cmp::Ord; use std::ops; use std::path::PathBuf; +use crate::base64; use num_derive::FromPrimitive; use serde::{Deserialize, Serialize}; use serde_repr::*; -use crate::base64; // currently, we do assume that we record the whole program // so, we try to include minimal amount of data, @@ -474,5 +474,5 @@ pub enum EventLogKind { Error, // used for trace events TraceLogEvent, - EvmEvent + EvmEvent, } diff --git a/runtime_tracing/tests/binary_format.rs b/runtime_tracing/tests/binary_format.rs index b2f489f..ae818f4 100644 --- a/runtime_tracing/tests/binary_format.rs +++ b/runtime_tracing/tests/binary_format.rs @@ -1,15 +1,13 @@ use runtime_tracing::{create_trace_reader, create_trace_writer, TraceEventsFileFormat}; -use std::path::Path; use std::fs; +use std::path::Path; #[test] fn test_binary_roundtrip() { let json_path = Path::new("tests/data/trace.json"); let mut json_reader = create_trace_reader(TraceEventsFileFormat::Json); - let original = json_reader - .load_trace_events(json_path) - .unwrap(); + let original = json_reader.load_trace_events(json_path).unwrap(); let bin_path = Path::new("tests/data/trace.bin"); @@ -19,9 +17,7 @@ fn test_binary_roundtrip() { bin_writer.finish_writing_trace_events().unwrap(); let mut bin_reader = create_trace_reader(TraceEventsFileFormat::Binary); - let tracer2_events = bin_reader - .load_trace_events(bin_path) - .unwrap(); + let tracer2_events = bin_reader.load_trace_events(bin_path).unwrap(); fs::remove_file(bin_path).unwrap(); diff --git a/runtime_tracing_cli/src/main.rs b/runtime_tracing_cli/src/main.rs index 7e127a4..0877c1d 100644 --- a/runtime_tracing_cli/src/main.rs +++ b/runtime_tracing_cli/src/main.rs @@ -1,8 +1,8 @@ use std::path::Path; +use crate::fmt_trace_cmd::FmtTraceCommand; use clap::{Args, Parser, Subcommand}; use runtime_tracing::{create_trace_reader, create_trace_writer, TraceEventsFileFormat}; -use crate::fmt_trace_cmd::FmtTraceCommand; mod fmt_trace_cmd; #[derive(Debug, Clone, Args)] @@ -50,7 +50,7 @@ fn main() { trace_writer.begin_writing_trace_events(Path::new(&convert_command.output_file)).unwrap(); trace_writer.append_events(&mut trace_events); trace_writer.finish_writing_trace_events().unwrap(); - }, + } RuntimeTracingCliCommand::FormatTrace(fmt_trace_cmd) => { fmt_trace_cmd::run(fmt_trace_cmd); } diff --git a/trace_formatter/src/read_write_json.rs b/trace_formatter/src/read_write_json.rs index a801071..6c96843 100644 --- a/trace_formatter/src/read_write_json.rs +++ b/trace_formatter/src/read_write_json.rs @@ -4,8 +4,7 @@ use std::fs; pub fn serialize_file(src_filename: String) -> Value { let file_content = fs::read_to_string(src_filename).expect("Failed to read the file"); - serde_json::from_str(&file_content) - .expect("Failed to parse the json file that was given as a source") + serde_json::from_str(&file_content).expect("Failed to parse the json file that was given as a source") } pub fn save_to_file(dest_filename: String, json_string: String) { @@ -13,7 +12,5 @@ pub fn save_to_file(dest_filename: String, json_string: String) { if !json_string_copy.ends_with('\n') { json_string_copy.push('\n'); } - fs::write(&dest_filename, json_string_copy).unwrap_or_else(|_| { - panic!("Unable to write to destination file: {}", dest_filename.as_str()) - }); + fs::write(&dest_filename, json_string_copy).unwrap_or_else(|_| panic!("Unable to write to destination file: {}", dest_filename.as_str())); } From edd7065f6d928f66d64526fbcb234575717934ba Mon Sep 17 00:00:00 2001 From: Nikolay Nikolov Date: Wed, 16 Jul 2025 19:06:55 +0300 Subject: [PATCH 30/30] chore: bump runtime_tracing version to 0.13.0 --- runtime_tracing/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime_tracing/Cargo.toml b/runtime_tracing/Cargo.toml index 4e2d48a..665bd2e 100644 --- a/runtime_tracing/Cargo.toml +++ b/runtime_tracing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "runtime_tracing" -version = "0.12.2" +version = "0.13.0" edition = "2021" authors = ["Metacraft Labs Ltd"] description = "A library for the schema and tracing helpers for the CodeTracer db trace format"