diff --git a/Cargo.toml b/Cargo.toml index 5bdf8f0..ebf7c30 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,19 @@ [workspace] resolver = "2" -members = ["runtime_tracing", "runtime_tracing_cli", "trace_formatter"] +members = [ + "codetracer_trace_types", + "codetracer_trace_format_capnp", + "codetracer_trace_format_cbor_zstd", + "codetracer_trace_reader", + "codetracer_trace_writer", + "codetracer_trace_util", + "trace_formatter", +] [workspace.dependencies] -runtime_tracing = { path = "runtime_tracing/" } trace_formatter = { path = "trace_formatter/"} +codetracer_trace_types = { path = "codetracer_trace_types" } +codetracer_trace_format_capnp = { path = "codetracer_trace_format_capnp" } +codetracer_trace_format_cbor_zstd = { path = "codetracer_trace_format_cbor_zstd" } +codetracer_trace_reader = { path = "codetracer_trace_reader" } +codetracer_trace_writer = { path = "codetracer_trace_writer" } diff --git a/codetracer_trace_format_capnp/Cargo.toml b/codetracer_trace_format_capnp/Cargo.toml new file mode 100644 index 0000000..7553823 --- /dev/null +++ b/codetracer_trace_format_capnp/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "codetracer_trace_format_capnp" +version = "0.16.0" +edition = "2024" +authors = ["Metacraft Labs Ltd"] +description = "A library containing some helpers, used internally in the reading and writing of the CodeTracer db trace format" +repository = "https://github.com/metacraft-labs/runtime_tracing" +license = "MIT" +keywords = ["debugging", "development-tools"] + +[dependencies] +codetracer_trace_types.workspace = true +capnp = "0.21.1" + +[build-dependencies] +capnpc = "0.21.0" diff --git a/runtime_tracing/build.rs b/codetracer_trace_format_capnp/build.rs similarity index 100% rename from runtime_tracing/build.rs rename to codetracer_trace_format_capnp/build.rs diff --git a/runtime_tracing/src/capnptrace.rs b/codetracer_trace_format_capnp/src/capnptrace.rs similarity index 55% rename from runtime_tracing/src/capnptrace.rs rename to codetracer_trace_format_capnp/src/capnptrace.rs index 07eb176..2e277bf 100644 --- a/runtime_tracing/src/capnptrace.rs +++ b/codetracer_trace_format_capnp/src/capnptrace.rs @@ -1,5 +1,5 @@ use crate::trace_capnp::trace; -use crate::{TraceLowLevelEvent, VariableId}; +use codetracer_trace_types::{TraceLowLevelEvent, VariableId}; use capnp::serialize_packed; use std::str::FromStr; @@ -9,166 +9,166 @@ use std::str::FromStr; /// The header is 8 bytes in size, ensuring 64-bit alignment for the rest of the file. pub const HEADER: &[u8] = &[0xC0, 0xDE, 0x72, 0xAC, 0xE2, 0x00, 0x00, 0x00]; -impl From for trace::TypeKind { - fn from(item: crate::TypeKind) -> Self { +impl From for trace::TypeKind { + fn from(item: codetracer_trace_types::TypeKind) -> Self { match item { - crate::TypeKind::Seq => trace::TypeKind::Seq, - crate::TypeKind::Set => trace::TypeKind::Set, - crate::TypeKind::HashSet => trace::TypeKind::HashSet, - crate::TypeKind::OrderedSet => trace::TypeKind::OrderedSet, - crate::TypeKind::Array => trace::TypeKind::Array, - crate::TypeKind::Varargs => trace::TypeKind::Varargs, - crate::TypeKind::Struct => trace::TypeKind::Struct, - crate::TypeKind::Int => trace::TypeKind::Int, - crate::TypeKind::Float => trace::TypeKind::Float, - crate::TypeKind::String => trace::TypeKind::String, - crate::TypeKind::CString => trace::TypeKind::Cstring, - crate::TypeKind::Char => trace::TypeKind::Char, - crate::TypeKind::Bool => trace::TypeKind::Bool, - crate::TypeKind::Literal => trace::TypeKind::Literal, - crate::TypeKind::Ref => trace::TypeKind::Ref, - crate::TypeKind::Recursion => trace::TypeKind::Recursion, - crate::TypeKind::Raw => trace::TypeKind::Raw, - crate::TypeKind::Enum => trace::TypeKind::Enum, - crate::TypeKind::Enum16 => trace::TypeKind::Enum16, - crate::TypeKind::Enum32 => trace::TypeKind::Enum32, - crate::TypeKind::C => trace::TypeKind::C, - crate::TypeKind::TableKind => trace::TypeKind::TableKind, - crate::TypeKind::Union => trace::TypeKind::Union, - crate::TypeKind::Pointer => trace::TypeKind::Pointer, - crate::TypeKind::Error => trace::TypeKind::Error, - crate::TypeKind::FunctionKind => trace::TypeKind::FunctionKind, - crate::TypeKind::TypeValue => trace::TypeKind::TypeValue, - crate::TypeKind::Tuple => trace::TypeKind::Tuple, - crate::TypeKind::Variant => trace::TypeKind::Variant, - crate::TypeKind::Html => trace::TypeKind::Html, - crate::TypeKind::None => trace::TypeKind::None, - crate::TypeKind::NonExpanded => trace::TypeKind::NonExpanded, - crate::TypeKind::Any => trace::TypeKind::Any, - crate::TypeKind::Slice => trace::TypeKind::Slice, + codetracer_trace_types::TypeKind::Seq => trace::TypeKind::Seq, + codetracer_trace_types::TypeKind::Set => trace::TypeKind::Set, + codetracer_trace_types::TypeKind::HashSet => trace::TypeKind::HashSet, + codetracer_trace_types::TypeKind::OrderedSet => trace::TypeKind::OrderedSet, + codetracer_trace_types::TypeKind::Array => trace::TypeKind::Array, + codetracer_trace_types::TypeKind::Varargs => trace::TypeKind::Varargs, + codetracer_trace_types::TypeKind::Struct => trace::TypeKind::Struct, + codetracer_trace_types::TypeKind::Int => trace::TypeKind::Int, + codetracer_trace_types::TypeKind::Float => trace::TypeKind::Float, + codetracer_trace_types::TypeKind::String => trace::TypeKind::String, + codetracer_trace_types::TypeKind::CString => trace::TypeKind::Cstring, + codetracer_trace_types::TypeKind::Char => trace::TypeKind::Char, + codetracer_trace_types::TypeKind::Bool => trace::TypeKind::Bool, + codetracer_trace_types::TypeKind::Literal => trace::TypeKind::Literal, + codetracer_trace_types::TypeKind::Ref => trace::TypeKind::Ref, + codetracer_trace_types::TypeKind::Recursion => trace::TypeKind::Recursion, + codetracer_trace_types::TypeKind::Raw => trace::TypeKind::Raw, + codetracer_trace_types::TypeKind::Enum => trace::TypeKind::Enum, + codetracer_trace_types::TypeKind::Enum16 => trace::TypeKind::Enum16, + codetracer_trace_types::TypeKind::Enum32 => trace::TypeKind::Enum32, + codetracer_trace_types::TypeKind::C => trace::TypeKind::C, + codetracer_trace_types::TypeKind::TableKind => trace::TypeKind::TableKind, + codetracer_trace_types::TypeKind::Union => trace::TypeKind::Union, + codetracer_trace_types::TypeKind::Pointer => trace::TypeKind::Pointer, + codetracer_trace_types::TypeKind::Error => trace::TypeKind::Error, + codetracer_trace_types::TypeKind::FunctionKind => trace::TypeKind::FunctionKind, + codetracer_trace_types::TypeKind::TypeValue => trace::TypeKind::TypeValue, + codetracer_trace_types::TypeKind::Tuple => trace::TypeKind::Tuple, + codetracer_trace_types::TypeKind::Variant => trace::TypeKind::Variant, + codetracer_trace_types::TypeKind::Html => trace::TypeKind::Html, + codetracer_trace_types::TypeKind::None => trace::TypeKind::None, + codetracer_trace_types::TypeKind::NonExpanded => trace::TypeKind::NonExpanded, + codetracer_trace_types::TypeKind::Any => trace::TypeKind::Any, + codetracer_trace_types::TypeKind::Slice => trace::TypeKind::Slice, } } } -impl From for crate::TypeKind { +impl From for codetracer_trace_types::TypeKind { fn from(item: trace::TypeKind) -> Self { match item { - trace::TypeKind::Seq => crate::TypeKind::Seq, - trace::TypeKind::Set => crate::TypeKind::Set, - trace::TypeKind::HashSet => crate::TypeKind::HashSet, - trace::TypeKind::OrderedSet => crate::TypeKind::OrderedSet, - trace::TypeKind::Array => crate::TypeKind::Array, - trace::TypeKind::Varargs => crate::TypeKind::Varargs, - trace::TypeKind::Struct => crate::TypeKind::Struct, - trace::TypeKind::Int => crate::TypeKind::Int, - trace::TypeKind::Float => crate::TypeKind::Float, - trace::TypeKind::String => crate::TypeKind::String, - trace::TypeKind::Cstring => crate::TypeKind::CString, - trace::TypeKind::Char => crate::TypeKind::Char, - trace::TypeKind::Bool => crate::TypeKind::Bool, - trace::TypeKind::Literal => crate::TypeKind::Literal, - trace::TypeKind::Ref => crate::TypeKind::Ref, - trace::TypeKind::Recursion => crate::TypeKind::Recursion, - trace::TypeKind::Raw => crate::TypeKind::Raw, - trace::TypeKind::Enum => crate::TypeKind::Enum, - trace::TypeKind::Enum16 => crate::TypeKind::Enum16, - trace::TypeKind::Enum32 => crate::TypeKind::Enum32, - trace::TypeKind::C => crate::TypeKind::C, - trace::TypeKind::TableKind => crate::TypeKind::TableKind, - trace::TypeKind::Union => crate::TypeKind::Union, - trace::TypeKind::Pointer => crate::TypeKind::Pointer, - trace::TypeKind::Error => crate::TypeKind::Error, - trace::TypeKind::FunctionKind => crate::TypeKind::FunctionKind, - trace::TypeKind::TypeValue => crate::TypeKind::TypeValue, - trace::TypeKind::Tuple => crate::TypeKind::Tuple, - trace::TypeKind::Variant => crate::TypeKind::Variant, - trace::TypeKind::Html => crate::TypeKind::Html, - trace::TypeKind::None => crate::TypeKind::None, - trace::TypeKind::NonExpanded => crate::TypeKind::NonExpanded, - trace::TypeKind::Any => crate::TypeKind::Any, - trace::TypeKind::Slice => crate::TypeKind::Slice, + trace::TypeKind::Seq => codetracer_trace_types::TypeKind::Seq, + trace::TypeKind::Set => codetracer_trace_types::TypeKind::Set, + trace::TypeKind::HashSet => codetracer_trace_types::TypeKind::HashSet, + trace::TypeKind::OrderedSet => codetracer_trace_types::TypeKind::OrderedSet, + trace::TypeKind::Array => codetracer_trace_types::TypeKind::Array, + trace::TypeKind::Varargs => codetracer_trace_types::TypeKind::Varargs, + trace::TypeKind::Struct => codetracer_trace_types::TypeKind::Struct, + trace::TypeKind::Int => codetracer_trace_types::TypeKind::Int, + trace::TypeKind::Float => codetracer_trace_types::TypeKind::Float, + trace::TypeKind::String => codetracer_trace_types::TypeKind::String, + trace::TypeKind::Cstring => codetracer_trace_types::TypeKind::CString, + trace::TypeKind::Char => codetracer_trace_types::TypeKind::Char, + trace::TypeKind::Bool => codetracer_trace_types::TypeKind::Bool, + trace::TypeKind::Literal => codetracer_trace_types::TypeKind::Literal, + trace::TypeKind::Ref => codetracer_trace_types::TypeKind::Ref, + trace::TypeKind::Recursion => codetracer_trace_types::TypeKind::Recursion, + trace::TypeKind::Raw => codetracer_trace_types::TypeKind::Raw, + trace::TypeKind::Enum => codetracer_trace_types::TypeKind::Enum, + trace::TypeKind::Enum16 => codetracer_trace_types::TypeKind::Enum16, + trace::TypeKind::Enum32 => codetracer_trace_types::TypeKind::Enum32, + trace::TypeKind::C => codetracer_trace_types::TypeKind::C, + trace::TypeKind::TableKind => codetracer_trace_types::TypeKind::TableKind, + trace::TypeKind::Union => codetracer_trace_types::TypeKind::Union, + trace::TypeKind::Pointer => codetracer_trace_types::TypeKind::Pointer, + trace::TypeKind::Error => codetracer_trace_types::TypeKind::Error, + trace::TypeKind::FunctionKind => codetracer_trace_types::TypeKind::FunctionKind, + trace::TypeKind::TypeValue => codetracer_trace_types::TypeKind::TypeValue, + trace::TypeKind::Tuple => codetracer_trace_types::TypeKind::Tuple, + trace::TypeKind::Variant => codetracer_trace_types::TypeKind::Variant, + trace::TypeKind::Html => codetracer_trace_types::TypeKind::Html, + trace::TypeKind::None => codetracer_trace_types::TypeKind::None, + trace::TypeKind::NonExpanded => codetracer_trace_types::TypeKind::NonExpanded, + trace::TypeKind::Any => codetracer_trace_types::TypeKind::Any, + trace::TypeKind::Slice => codetracer_trace_types::TypeKind::Slice, } } } -impl From for crate::EventLogKind { +impl From for codetracer_trace_types::EventLogKind { fn from(value: trace::EventLogKind) -> Self { match value { - trace::EventLogKind::Write => crate::EventLogKind::Write, - trace::EventLogKind::WriteFile => crate::EventLogKind::WriteFile, - trace::EventLogKind::WriteOther => crate::EventLogKind::WriteOther, - trace::EventLogKind::Read => crate::EventLogKind::Read, - trace::EventLogKind::ReadFile => crate::EventLogKind::ReadFile, - trace::EventLogKind::ReadOther => crate::EventLogKind::ReadOther, - trace::EventLogKind::ReadDir => crate::EventLogKind::ReadDir, - trace::EventLogKind::OpenDir => crate::EventLogKind::OpenDir, - trace::EventLogKind::CloseDir => crate::EventLogKind::CloseDir, - trace::EventLogKind::Socket => crate::EventLogKind::Socket, - trace::EventLogKind::Open => crate::EventLogKind::Open, - trace::EventLogKind::Error => crate::EventLogKind::Error, - trace::EventLogKind::TraceLogEvent => crate::EventLogKind::TraceLogEvent, - trace::EventLogKind::EvmEvent => crate::EventLogKind::EvmEvent, + trace::EventLogKind::Write => codetracer_trace_types::EventLogKind::Write, + trace::EventLogKind::WriteFile => codetracer_trace_types::EventLogKind::WriteFile, + trace::EventLogKind::WriteOther => codetracer_trace_types::EventLogKind::WriteOther, + trace::EventLogKind::Read => codetracer_trace_types::EventLogKind::Read, + trace::EventLogKind::ReadFile => codetracer_trace_types::EventLogKind::ReadFile, + trace::EventLogKind::ReadOther => codetracer_trace_types::EventLogKind::ReadOther, + trace::EventLogKind::ReadDir => codetracer_trace_types::EventLogKind::ReadDir, + trace::EventLogKind::OpenDir => codetracer_trace_types::EventLogKind::OpenDir, + trace::EventLogKind::CloseDir => codetracer_trace_types::EventLogKind::CloseDir, + trace::EventLogKind::Socket => codetracer_trace_types::EventLogKind::Socket, + trace::EventLogKind::Open => codetracer_trace_types::EventLogKind::Open, + trace::EventLogKind::Error => codetracer_trace_types::EventLogKind::Error, + trace::EventLogKind::TraceLogEvent => codetracer_trace_types::EventLogKind::TraceLogEvent, + trace::EventLogKind::EvmEvent => codetracer_trace_types::EventLogKind::EvmEvent, } } } -impl From for trace::EventLogKind { - fn from(value: crate::EventLogKind) -> Self { +impl From for trace::EventLogKind { + fn from(value: codetracer_trace_types::EventLogKind) -> Self { match value { - crate::EventLogKind::Write => trace::EventLogKind::Write, - crate::EventLogKind::WriteFile => trace::EventLogKind::WriteFile, - crate::EventLogKind::WriteOther => trace::EventLogKind::WriteOther, - crate::EventLogKind::Read => trace::EventLogKind::Read, - crate::EventLogKind::ReadFile => trace::EventLogKind::ReadFile, - crate::EventLogKind::ReadOther => trace::EventLogKind::ReadOther, - crate::EventLogKind::ReadDir => trace::EventLogKind::ReadDir, - crate::EventLogKind::OpenDir => trace::EventLogKind::OpenDir, - crate::EventLogKind::CloseDir => trace::EventLogKind::CloseDir, - crate::EventLogKind::Socket => trace::EventLogKind::Socket, - crate::EventLogKind::Open => trace::EventLogKind::Open, - crate::EventLogKind::Error => trace::EventLogKind::Error, - crate::EventLogKind::TraceLogEvent => trace::EventLogKind::TraceLogEvent, - crate::EventLogKind::EvmEvent => trace::EventLogKind::EvmEvent, + codetracer_trace_types::EventLogKind::Write => trace::EventLogKind::Write, + codetracer_trace_types::EventLogKind::WriteFile => trace::EventLogKind::WriteFile, + codetracer_trace_types::EventLogKind::WriteOther => trace::EventLogKind::WriteOther, + codetracer_trace_types::EventLogKind::Read => trace::EventLogKind::Read, + codetracer_trace_types::EventLogKind::ReadFile => trace::EventLogKind::ReadFile, + codetracer_trace_types::EventLogKind::ReadOther => trace::EventLogKind::ReadOther, + codetracer_trace_types::EventLogKind::ReadDir => trace::EventLogKind::ReadDir, + codetracer_trace_types::EventLogKind::OpenDir => trace::EventLogKind::OpenDir, + codetracer_trace_types::EventLogKind::CloseDir => trace::EventLogKind::CloseDir, + codetracer_trace_types::EventLogKind::Socket => trace::EventLogKind::Socket, + codetracer_trace_types::EventLogKind::Open => trace::EventLogKind::Open, + codetracer_trace_types::EventLogKind::Error => trace::EventLogKind::Error, + codetracer_trace_types::EventLogKind::TraceLogEvent => trace::EventLogKind::TraceLogEvent, + codetracer_trace_types::EventLogKind::EvmEvent => trace::EventLogKind::EvmEvent, } } } -impl From for trace::PassBy { - fn from(value: crate::PassBy) -> Self { +impl From for trace::PassBy { + fn from(value: codetracer_trace_types::PassBy) -> Self { match value { - crate::PassBy::Value => trace::PassBy::Value, - crate::PassBy::Reference => trace::PassBy::Reference, + codetracer_trace_types::PassBy::Value => trace::PassBy::Value, + codetracer_trace_types::PassBy::Reference => trace::PassBy::Reference, } } } -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: &codetracer_trace_types::ValueRecord) { match vr { - crate::ValueRecord::Int { i, type_id } => { + codetracer_trace_types::ValueRecord::Int { i, type_id } => { let mut qi = bldr.init_int(); qi.set_i(*i); let mut q_typ_id = qi.init_type_id(); q_typ_id.set_i(type_id.0.try_into().unwrap()); } - crate::ValueRecord::Float { f, type_id } => { + codetracer_trace_types::ValueRecord::Float { f, type_id } => { let mut qf = bldr.init_float(); qf.set_f(*f); let mut q_typ_id = qf.init_type_id(); q_typ_id.set_i(type_id.0.try_into().unwrap()); } - crate::ValueRecord::Bool { b, type_id } => { + codetracer_trace_types::ValueRecord::Bool { b, type_id } => { let mut qb = bldr.init_bool(); qb.set_b(*b); let mut q_typ_id = qb.init_type_id(); q_typ_id.set_i(type_id.0.try_into().unwrap()); } - crate::ValueRecord::String { text, type_id } => { + codetracer_trace_types::ValueRecord::String { text, type_id } => { let mut qs = bldr.init_string(); qs.set_text(text); 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 } => { + codetracer_trace_types::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()); for i in 0..elements.len() { @@ -180,7 +180,7 @@ fn conv_valuerecord(bldr: crate::trace_capnp::trace::value_record::Builder, vr: let mut q_typ_id = qseq.init_type_id(); q_typ_id.set_i(type_id.0.try_into().unwrap()); } - crate::ValueRecord::Tuple { elements, type_id } => { + codetracer_trace_types::ValueRecord::Tuple { elements, type_id } => { let mut qtup = bldr.init_tuple(); let mut elems = qtup.reborrow().init_elements(elements.len().try_into().unwrap()); for i in 0..elements.len() { @@ -191,7 +191,7 @@ fn conv_valuerecord(bldr: crate::trace_capnp::trace::value_record::Builder, vr: 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 } => { + codetracer_trace_types::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()); for i in 0..field_values.len() { @@ -202,7 +202,7 @@ fn conv_valuerecord(bldr: crate::trace_capnp::trace::value_record::Builder, vr: let mut q_typ_id = qstruc.init_type_id(); q_typ_id.set_i(type_id.0.try_into().unwrap()); } - crate::ValueRecord::Variant { + codetracer_trace_types::ValueRecord::Variant { discriminator, contents, type_id, @@ -214,7 +214,7 @@ fn conv_valuerecord(bldr: crate::trace_capnp::trace::value_record::Builder, vr: let mut q_typ_id = qvariant.init_type_id(); q_typ_id.set_i(type_id.0.try_into().unwrap()); } - crate::ValueRecord::Reference { + codetracer_trace_types::ValueRecord::Reference { dereferenced, address, mutable, @@ -228,29 +228,29 @@ fn conv_valuerecord(bldr: crate::trace_capnp::trace::value_record::Builder, vr: let mut q_typ_id = qreference.init_type_id(); q_typ_id.set_i(type_id.0.try_into().unwrap()); } - crate::ValueRecord::Raw { r, type_id } => { + codetracer_trace_types::ValueRecord::Raw { r, type_id } => { let mut qraw = bldr.init_raw(); qraw.set_r(r); let mut q_typ_id = qraw.init_type_id(); q_typ_id.set_i(type_id.0.try_into().unwrap()); } - crate::ValueRecord::Error { msg, type_id } => { + codetracer_trace_types::ValueRecord::Error { msg, type_id } => { let mut qerr = bldr.init_error(); qerr.set_msg(msg); let mut q_typ_id = qerr.init_type_id(); q_typ_id.set_i(type_id.0.try_into().unwrap()); } - crate::ValueRecord::None { type_id } => { + codetracer_trace_types::ValueRecord::None { type_id } => { let qnone = bldr.init_none(); let mut q_typ_id = qnone.init_type_id(); q_typ_id.set_i(type_id.0.try_into().unwrap()); } - crate::ValueRecord::Cell { place } => { + codetracer_trace_types::ValueRecord::Cell { place } => { let qcell = bldr.init_cell(); let mut q_place = qcell.init_place(); q_place.set_p(place.0); } - crate::ValueRecord::BigInt { b, negative, type_id } => { + codetracer_trace_types::ValueRecord::BigInt { b, negative, type_id } => { let mut qbigint = bldr.init_bigint(); let mut bigint_b = qbigint.reborrow().init_b(b.len().try_into().unwrap()); for i in 0..=b.len() { @@ -263,7 +263,7 @@ fn conv_valuerecord(bldr: crate::trace_capnp::trace::value_record::Builder, vr: } } -pub fn write_trace(q: &[crate::TraceLowLevelEvent], output: &mut impl std::io::Write) -> ::capnp::Result<()> { +pub fn write_trace(q: &[codetracer_trace_types::TraceLowLevelEvent], output: &mut impl std::io::Write) -> ::capnp::Result<()> { let mut message = ::capnp::message::Builder::new_default(); let trace = message.init_root::(); @@ -280,10 +280,10 @@ pub fn write_trace(q: &[crate::TraceLowLevelEvent], output: &mut impl std::io::W typ.set_lang_type(type_record.lang_type.clone()); let mut specific_info = typ.init_specific_info(); match &type_record.specific_info { - crate::TypeSpecificInfo::None => { + codetracer_trace_types::TypeSpecificInfo::None => { specific_info.set_none(()); } - crate::TypeSpecificInfo::Struct { fields } => { + codetracer_trace_types::TypeSpecificInfo::Struct { fields } => { let strct = specific_info.init_struct(); let mut flds = strct.init_fields(fields.len().try_into().unwrap()); for i in 0..fields.len() { @@ -294,7 +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 } => { + codetracer_trace_types::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()); @@ -378,11 +378,11 @@ pub fn write_trace(q: &[crate::TraceLowLevelEvent], output: &mut impl std::io::W ret.set_pass_by(assrec.pass_by.clone().into()); let ret_from = ret.init_from(); match &assrec.from { - crate::RValue::Simple(variable_id) => { + codetracer_trace_types::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) => { + codetracer_trace_types::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()); @@ -461,87 +461,87 @@ 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 { + Ok(trace::value_record::Which::Int(q)) => Ok(codetracer_trace_types::ValueRecord::Int { i: q.get_i(), - type_id: crate::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), + type_id: codetracer_trace_types::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), }), - Ok(trace::value_record::Which::Float(q)) => Ok(crate::ValueRecord::Float { + Ok(trace::value_record::Which::Float(q)) => Ok(codetracer_trace_types::ValueRecord::Float { f: q.get_f(), - type_id: crate::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), + type_id: codetracer_trace_types::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), }), - Ok(trace::value_record::Which::Bool(q)) => Ok(crate::ValueRecord::Bool { + Ok(trace::value_record::Which::Bool(q)) => Ok(codetracer_trace_types::ValueRecord::Bool { b: q.get_b(), - type_id: crate::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), + type_id: codetracer_trace_types::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), }), - Ok(trace::value_record::Which::String(q)) => Ok(crate::ValueRecord::String { + Ok(trace::value_record::Which::String(q)) => Ok(codetracer_trace_types::ValueRecord::String { text: q.get_text()?.to_string()?, - type_id: crate::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), + type_id: codetracer_trace_types::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), }), - Ok(trace::value_record::Which::Sequence(q)) => Ok(crate::ValueRecord::Sequence { + Ok(trace::value_record::Which::Sequence(q)) => Ok(codetracer_trace_types::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()), + type_id: codetracer_trace_types::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), }), - Ok(trace::value_record::Which::Tuple(q)) => Ok(crate::ValueRecord::Tuple { + Ok(trace::value_record::Which::Tuple(q)) => Ok(codetracer_trace_types::ValueRecord::Tuple { elements: get_value_records(q.get_elements()?)?, - type_id: crate::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), + type_id: codetracer_trace_types::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), }), - Ok(trace::value_record::Which::Struct(q)) => Ok(crate::ValueRecord::Struct { + Ok(trace::value_record::Which::Struct(q)) => Ok(codetracer_trace_types::ValueRecord::Struct { field_values: get_value_records(q.get_field_values()?)?, - type_id: crate::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), + type_id: codetracer_trace_types::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), }), - Ok(trace::value_record::Which::Variant(q)) => Ok(crate::ValueRecord::Variant { + Ok(trace::value_record::Which::Variant(q)) => Ok(codetracer_trace_types::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()), + type_id: codetracer_trace_types::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), }), - Ok(trace::value_record::Which::Reference(q)) => Ok(crate::ValueRecord::Reference { + Ok(trace::value_record::Which::Reference(q)) => Ok(codetracer_trace_types::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()), + type_id: codetracer_trace_types::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), }), - Ok(trace::value_record::Which::Raw(q)) => Ok(crate::ValueRecord::Raw { + Ok(trace::value_record::Which::Raw(q)) => Ok(codetracer_trace_types::ValueRecord::Raw { r: q.get_r()?.to_string()?, - type_id: crate::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), + type_id: codetracer_trace_types::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), }), - Ok(trace::value_record::Which::Error(q)) => Ok(crate::ValueRecord::Error { + Ok(trace::value_record::Which::Error(q)) => Ok(codetracer_trace_types::ValueRecord::Error { msg: q.get_msg()?.to_string()?, - type_id: crate::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), + type_id: codetracer_trace_types::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), }), - Ok(trace::value_record::Which::None(q)) => Ok(crate::ValueRecord::None { - type_id: crate::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), + Ok(trace::value_record::Which::None(q)) => Ok(codetracer_trace_types::ValueRecord::None { + type_id: codetracer_trace_types::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), }), - Ok(trace::value_record::Which::Cell(q)) => Ok(crate::ValueRecord::Cell { - place: crate::Place(q.get_place()?.get_p()), + Ok(trace::value_record::Which::Cell(q)) => Ok(codetracer_trace_types::ValueRecord::Cell { + place: codetracer_trace_types::Place(q.get_place()?.get_p()), }), - Ok(trace::value_record::Which::Bigint(q)) => Ok(crate::ValueRecord::BigInt { + Ok(trace::value_record::Which::Bigint(q)) => Ok(codetracer_trace_types::ValueRecord::BigInt { b: q.get_b()?.as_slice().unwrap().to_vec(), negative: q.get_negative(), - type_id: crate::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), + type_id: codetracer_trace_types::TypeId(q.get_type_id()?.get_i().try_into().unwrap()), }), Err(_) => panic!(), } } -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()), +fn get_full_value_record(r: trace::full_value_record::Reader) -> Result { + Ok(codetracer_trace_types::FullValueRecord { + variable_id: codetracer_trace_types::VariableId(r.get_variable_id()?.get_i().try_into().unwrap()), value: get_value_record(r.get_value()?)?, }) } -pub fn read_trace(input: &mut impl std::io::BufRead) -> ::capnp::Result> { +pub fn read_trace(input: &mut impl std::io::BufRead) -> ::capnp::Result> { let mut header_buf = [0; 8]; input.read_exact(&mut header_buf)?; if header_buf != HEADER { @@ -551,15 +551,15 @@ 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()), - line: crate::Line(step_record.get_line()?.get_l()), + TraceLowLevelEvent::Step(codetracer_trace_types::StepRecord { + path_id: codetracer_trace_types::PathId(step_record.get_path_id()?.get_i().try_into().unwrap()), + line: codetracer_trace_types::Line(step_record.get_line()?.get_l()), }) } Ok(trace::trace_low_level_event::Which::Path(path_buf)) => { @@ -569,24 +569,24 @@ pub fn read_trace(input: &mut impl std::io::BufRead) -> ::capnp::Result TraceLowLevelEvent::Variable(variable?.to_string()?), Ok(trace::trace_low_level_event::Which::Type(type_record)) => { let type_record = type_record?; - TraceLowLevelEvent::Type(crate::TypeRecord { + TraceLowLevelEvent::Type(codetracer_trace_types::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(())) => codetracer_trace_types::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 { + fields.push(codetracer_trace_types::FieldTypeRecord { name: s_field.get_name()?.to_string()?, - type_id: crate::TypeId(s_field.get_type_id()?.get_i().try_into().unwrap()), + type_id: codetracer_trace_types::TypeId(s_field.get_type_id()?.get_i().try_into().unwrap()), }); } - crate::TypeSpecificInfo::Struct { fields } + codetracer_trace_types::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)) => codetracer_trace_types::TypeSpecificInfo::Pointer { + dereference_type_id: codetracer_trace_types::TypeId(p.get_dereference_type_id()?.get_i().try_into().unwrap()), }, Err(_) => { panic!() @@ -597,33 +597,33 @@ pub fn read_trace(input: &mut impl std::io::BufRead) -> ::capnp::Result 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()), - line: crate::Line(function_record.get_line()?.get_l()), + TraceLowLevelEvent::Function(codetracer_trace_types::FunctionRecord { + path_id: codetracer_trace_types::PathId(function_record.get_path_id()?.get_i().try_into().unwrap()), + line: codetracer_trace_types::Line(function_record.get_line()?.get_l()), name: function_record.get_name()?.to_string()?, }) } Ok(trace::trace_low_level_event::Which::Call(call_record)) => { 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()), + args.push(codetracer_trace_types::FullValueRecord { + variable_id: codetracer_trace_types::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()), + TraceLowLevelEvent::Call(codetracer_trace_types::CallRecord { + function_id: codetracer_trace_types::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 { + Ok(trace::trace_low_level_event::Which::Return(return_record)) => TraceLowLevelEvent::Return(codetracer_trace_types::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 { + TraceLowLevelEvent::Event(codetracer_trace_types::RecordEvent { kind: record_event.get_kind()?.into(), metadata: record_event.get_metadata()?.to_string()?, content: record_event.get_content()?.to_string()?, @@ -639,89 +639,89 @@ 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()), - place: crate::Place(bind_variable_record.get_place()?.get_p()), + TraceLowLevelEvent::BindVariable(codetracer_trace_types::BindVariableRecord { + variable_id: codetracer_trace_types::VariableId(bind_variable_record.get_variable_id()?.get_i().try_into().unwrap()), + place: codetracer_trace_types::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()), + TraceLowLevelEvent::Assignment(codetracer_trace_types::AssignmentRecord { + to: codetracer_trace_types::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, + trace::PassBy::Value => codetracer_trace_types::PassBy::Value, + trace::PassBy::Reference => codetracer_trace_types::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())) + codetracer_trace_types::RValue::Simple(codetracer_trace_types::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()); for vv in variables { - v.push(crate::VariableId(vv.get_i().try_into().unwrap())); + v.push(codetracer_trace_types::VariableId(vv.get_i().try_into().unwrap())); } - crate::RValue::Compound(v) + codetracer_trace_types::RValue::Compound(v) } }, }) } Ok(trace::trace_low_level_event::Which::DropVariables(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(codetracer_trace_types::VariableId(vv.get_i().try_into().unwrap())) } TraceLowLevelEvent::DropVariables(v) } Ok(trace::trace_low_level_event::Which::CompoundValue(compound_value_record)) => { let compound_value_record = compound_value_record?; - TraceLowLevelEvent::CompoundValue(crate::CompoundValueRecord { - place: crate::Place(compound_value_record.get_place()?.get_p()), + TraceLowLevelEvent::CompoundValue(codetracer_trace_types::CompoundValueRecord { + place: codetracer_trace_types::Place(compound_value_record.get_place()?.get_p()), value: get_value_record(compound_value_record.get_value()?)?, }) } Ok(trace::trace_low_level_event::Which::CellValue(cell_value_record)) => { let cell_value_record = cell_value_record?; - TraceLowLevelEvent::CellValue(crate::CellValueRecord { - place: crate::Place(cell_value_record.get_place()?.get_p()), + TraceLowLevelEvent::CellValue(codetracer_trace_types::CellValueRecord { + place: codetracer_trace_types::Place(cell_value_record.get_place()?.get_p()), value: get_value_record(cell_value_record.get_value()?)?, }) } 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()), + TraceLowLevelEvent::AssignCompoundItem(codetracer_trace_types::AssignCompoundItemRecord { + place: codetracer_trace_types::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()), + item_place: codetracer_trace_types::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?; - TraceLowLevelEvent::AssignCell(crate::AssignCellRecord { - place: crate::Place(assign_cell_record.get_place()?.get_p()), + TraceLowLevelEvent::AssignCell(codetracer_trace_types::AssignCellRecord { + place: codetracer_trace_types::Place(assign_cell_record.get_place()?.get_p()), new_value: get_value_record(assign_cell_record.get_new_value()?)?, }) } Ok(trace::trace_low_level_event::Which::VariableCell(variable_cell_record)) => { 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()), - place: crate::Place(variable_cell_record.get_place()?.get_p()), + TraceLowLevelEvent::VariableCell(codetracer_trace_types::VariableCellRecord { + variable_id: codetracer_trace_types::VariableId(variable_cell_record.get_variable_id()?.get_i().try_into().unwrap()), + place: codetracer_trace_types::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())) + TraceLowLevelEvent::DropVariable(codetracer_trace_types::VariableId(variable_id?.get_i().try_into().unwrap())) } Ok(trace::trace_low_level_event::Which::ThreadStart(thread_id)) => { - TraceLowLevelEvent::ThreadStart(crate::ThreadId(thread_id?.get_i())) + TraceLowLevelEvent::ThreadStart(codetracer_trace_types::ThreadId(thread_id?.get_i())) } Ok(trace::trace_low_level_event::Which::ThreadExit(thread_id)) => { - TraceLowLevelEvent::ThreadExit(crate::ThreadId(thread_id?.get_i())) + TraceLowLevelEvent::ThreadExit(codetracer_trace_types::ThreadId(thread_id?.get_i())) } Ok(trace::trace_low_level_event::Which::ThreadSwitch(thread_id)) => { - TraceLowLevelEvent::ThreadSwitch(crate::ThreadId(thread_id?.get_i())) + TraceLowLevelEvent::ThreadSwitch(codetracer_trace_types::ThreadId(thread_id?.get_i())) } Ok(trace::trace_low_level_event::Which::DropLastStep(())) => TraceLowLevelEvent::DropLastStep, Err(_) => { diff --git a/codetracer_trace_format_capnp/src/lib.rs b/codetracer_trace_format_capnp/src/lib.rs new file mode 100644 index 0000000..dbb173e --- /dev/null +++ b/codetracer_trace_format_capnp/src/lib.rs @@ -0,0 +1,5 @@ +pub mod capnptrace; + +pub mod trace_capnp { + include!(concat!(env!("OUT_DIR"), "/src/trace_capnp.rs")); +} diff --git a/runtime_tracing/src/trace.capnp b/codetracer_trace_format_capnp/src/trace.capnp similarity index 100% rename from runtime_tracing/src/trace.capnp rename to codetracer_trace_format_capnp/src/trace.capnp diff --git a/codetracer_trace_format_cbor_zstd/Cargo.toml b/codetracer_trace_format_cbor_zstd/Cargo.toml new file mode 100644 index 0000000..15270f6 --- /dev/null +++ b/codetracer_trace_format_cbor_zstd/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "codetracer_trace_format_cbor_zstd" +version = "0.16.0" +edition = "2024" +authors = ["Metacraft Labs Ltd"] +description = "A library containing some helpers, used internally in the reading and writing of the CodeTracer db trace format" +repository = "https://github.com/metacraft-labs/runtime_tracing" +license = "MIT" +keywords = ["debugging", "development-tools"] diff --git a/codetracer_trace_format_cbor_zstd/src/lib.rs b/codetracer_trace_format_cbor_zstd/src/lib.rs new file mode 100644 index 0000000..b262254 --- /dev/null +++ b/codetracer_trace_format_cbor_zstd/src/lib.rs @@ -0,0 +1,7 @@ +/// The next 3 bytes are reserved/version info. +/// The header is 8 bytes in size, ensuring 64-bit alignment for the rest of the file. +pub const HEADERV1: &[u8] = &[ + 0xC0, 0xDE, 0x72, 0xAC, 0xE2, // The first 5 bytes identify the file as a CodeTracer file (hex l33tsp33k - C0DE72ACE2 for "CodeTracer"). + 0x01, // Indicates version 1 of the file format + 0x00, 0x00, +]; // Reserved, must be zero in this version. diff --git a/codetracer_trace_reader/Cargo.toml b/codetracer_trace_reader/Cargo.toml new file mode 100644 index 0000000..9c7acdc --- /dev/null +++ b/codetracer_trace_reader/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "codetracer_trace_reader" +version = "0.16.0" +edition = "2024" +authors = ["Metacraft Labs Ltd"] +description = "A library for reading the CodeTracer db trace format" +repository = "https://github.com/metacraft-labs/runtime_tracing" +license = "MIT" +keywords = ["debugging", "development-tools"] + +[dependencies] +codetracer_trace_types.workspace = true +codetracer_trace_format_capnp.workspace = true +codetracer_trace_format_cbor_zstd.workspace = true +fscommon = "0.1.1" +serde_json = "1.0" +cbor4ii = { version = "1.0.0", features = ["serde1", "use_std"] } + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +zeekstd = "0.6.0" + +[target.'cfg(target_arch = "wasm32")'.dependencies] +ruzstd = "0.8.1" diff --git a/runtime_tracing/src/cbor_zstd_reader.rs b/codetracer_trace_reader/src/cbor_zstd_reader.rs similarity index 92% rename from runtime_tracing/src/cbor_zstd_reader.rs rename to codetracer_trace_reader/src/cbor_zstd_reader.rs index c444768..89f3d32 100644 --- a/runtime_tracing/src/cbor_zstd_reader.rs +++ b/codetracer_trace_reader/src/cbor_zstd_reader.rs @@ -1,10 +1,11 @@ use std::io::{self, BufRead, BufReader, Read, Seek, Write}; +use codetracer_trace_format_cbor_zstd::HEADERV1; use fscommon::StreamSlice; use zeekstd::Decoder; -use crate::{TraceLowLevelEvent, cbor_zstd_writer::HEADERV1}; +use codetracer_trace_types::TraceLowLevelEvent; fn is_at_eof(reader: &mut R) -> io::Result { let buffer = reader.fill_buf()?; diff --git a/runtime_tracing/src/cbor_zstd_reader_wasm.rs b/codetracer_trace_reader/src/cbor_zstd_reader_wasm.rs similarity index 92% rename from runtime_tracing/src/cbor_zstd_reader_wasm.rs rename to codetracer_trace_reader/src/cbor_zstd_reader_wasm.rs index 03c88dd..7092096 100644 --- a/runtime_tracing/src/cbor_zstd_reader_wasm.rs +++ b/codetracer_trace_reader/src/cbor_zstd_reader_wasm.rs @@ -4,7 +4,8 @@ use fscommon::StreamSlice; use ruzstd::decoding::StreamingDecoder; -use crate::{TraceLowLevelEvent, cbor_zstd_writer::HEADERV1}; +use codetracer_trace_format_cbor_zstd::HEADERV1; +use codetracer_trace_types::TraceLowLevelEvent; fn is_at_eof(reader: &mut R) -> io::Result { let buffer = reader.fill_buf()?; diff --git a/codetracer_trace_reader/src/lib.rs b/codetracer_trace_reader/src/lib.rs new file mode 100644 index 0000000..e74ac26 --- /dev/null +++ b/codetracer_trace_reader/src/lib.rs @@ -0,0 +1,22 @@ +mod trace_readers; + +#[cfg(target_arch = "wasm32")] +#[path = "./cbor_zstd_reader_wasm.rs"] +mod cbor_zstd_reader; + +#[cfg(not(target_arch = "wasm32"))] +mod cbor_zstd_reader; + +#[derive(Debug, Clone, Copy)] +pub enum TraceEventsFileFormat { + Json, + BinaryV0, + Binary, +} + +pub fn create_trace_reader(format: TraceEventsFileFormat) -> Box { + match format { + TraceEventsFileFormat::Json => Box::new(trace_readers::JsonTraceReader {}), + TraceEventsFileFormat::BinaryV0 | TraceEventsFileFormat::Binary => Box::new(trace_readers::BinaryTraceReader {}), + } +} diff --git a/runtime_tracing/src/trace_readers.rs b/codetracer_trace_reader/src/trace_readers.rs similarity index 86% rename from runtime_tracing/src/trace_readers.rs rename to codetracer_trace_reader/src/trace_readers.rs index 40d4821..c5839f4 100644 --- a/runtime_tracing/src/trace_readers.rs +++ b/codetracer_trace_reader/src/trace_readers.rs @@ -5,7 +5,10 @@ use std::{ path::Path, }; -use crate::{TraceEventsFileFormat, TraceLowLevelEvent, capnptrace::HEADER, cbor_zstd_writer::HEADERV1}; +use crate::TraceEventsFileFormat; +use codetracer_trace_format_cbor_zstd::HEADERV1; +use codetracer_trace_types::TraceLowLevelEvent; +use codetracer_trace_format_capnp::capnptrace::HEADER; pub trait TraceReader { fn load_trace_events(&mut self, path: &Path) -> Result, Box>; @@ -44,7 +47,7 @@ impl TraceReader for BinaryTraceReader { match ver { Some(TraceEventsFileFormat::BinaryV0) => { let mut buf_reader = BufReader::new(file); - Ok(crate::capnptrace::read_trace(&mut buf_reader)?) + Ok(codetracer_trace_format_capnp::capnptrace::read_trace(&mut buf_reader)?) } Some(TraceEventsFileFormat::Binary) => Ok(crate::cbor_zstd_reader::read_trace(&mut file)?), Some(TraceEventsFileFormat::Json) => { diff --git a/codetracer_trace_types/Cargo.toml b/codetracer_trace_types/Cargo.toml new file mode 100644 index 0000000..51ba872 --- /dev/null +++ b/codetracer_trace_types/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "codetracer_trace_types" +version = "0.16.0" +edition = "2024" +authors = ["Metacraft Labs Ltd"] +description = "A library for the schema for the CodeTracer db trace format" +repository = "https://github.com/metacraft-labs/runtime_tracing" +license = "MIT" +keywords = ["debugging", "development-tools"] + +[dependencies] +base64 = "0.22.1" +num-traits = "0.2" +num-derive = "0.4" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +serde_repr = "0.1" +schemars = "0.8.2" diff --git a/runtime_tracing/src/base64.rs b/codetracer_trace_types/src/base64.rs similarity index 100% rename from runtime_tracing/src/base64.rs rename to codetracer_trace_types/src/base64.rs diff --git a/codetracer_trace_types/src/lib.rs b/codetracer_trace_types/src/lib.rs new file mode 100644 index 0000000..593e954 --- /dev/null +++ b/codetracer_trace_types/src/lib.rs @@ -0,0 +1,13 @@ +mod base64; +mod types; +pub use types::*; + +#[test] +fn test_equality_of_value_records() { + let a = ValueRecord::Int { i: 0, type_id: TypeId(0) }; // just an example type_id + let b = ValueRecord::Int { i: 0, type_id: TypeId(0) }; + let different = ValueRecord::Int { i: 1, type_id: TypeId(0) }; + + assert_eq!(a, b); + assert_ne!(a, different); +} diff --git a/runtime_tracing/src/types.rs b/codetracer_trace_types/src/types.rs similarity index 98% rename from runtime_tracing/src/types.rs rename to codetracer_trace_types/src/types.rs index 11e8fe8..365b7e7 100644 --- a/runtime_tracing/src/types.rs +++ b/codetracer_trace_types/src/types.rs @@ -18,6 +18,11 @@ use schemars::JsonSchema; // afterwards in postprocessing // this assumption can change in the future +pub const NONE_TYPE_ID: TypeId = TypeId(0); +pub const NONE_VALUE: ValueRecord = ValueRecord::None { type_id: NONE_TYPE_ID }; + +pub const TOP_LEVEL_FUNCTION_ID: FunctionId = FunctionId(0); + /// Low level building blocks that make up a recorded trace. #[derive(Debug, Clone, Serialize, Deserialize)] pub enum TraceLowLevelEvent { diff --git a/runtime_tracing_cli/Cargo.toml b/codetracer_trace_util/Cargo.toml similarity index 65% rename from runtime_tracing_cli/Cargo.toml rename to codetracer_trace_util/Cargo.toml index 60ec1e4..1bfb5f8 100644 --- a/runtime_tracing_cli/Cargo.toml +++ b/codetracer_trace_util/Cargo.toml @@ -1,13 +1,14 @@ [package] -name = "runtime_tracing_cli" -version = "0.1.0" -edition = "2021" +name = "codetracer_trace_util" +version = "0.2.0" +edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] clap = { version = "4.5.40", features = ["derive"] } -runtime_tracing.workspace = true +codetracer_trace_reader.workspace = true +codetracer_trace_writer.workspace = true trace_formatter.workspace = true serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/runtime_tracing_cli/src/fmt_trace_cmd.rs b/codetracer_trace_util/src/fmt_trace_cmd.rs similarity index 100% rename from runtime_tracing_cli/src/fmt_trace_cmd.rs rename to codetracer_trace_util/src/fmt_trace_cmd.rs diff --git a/runtime_tracing_cli/src/main.rs b/codetracer_trace_util/src/main.rs similarity index 62% rename from runtime_tracing_cli/src/main.rs rename to codetracer_trace_util/src/main.rs index f3ceb81..80a68d2 100644 --- a/runtime_tracing_cli/src/main.rs +++ b/codetracer_trace_util/src/main.rs @@ -2,7 +2,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, TraceWriter}; +use codetracer_trace_reader::create_trace_reader; +use codetracer_trace_writer::{create_trace_writer, trace_writer::TraceWriter}; mod fmt_trace_cmd; #[derive(Debug, Clone, Args)] @@ -27,11 +28,21 @@ struct RuntimeTracingCli { command: RuntimeTracingCliCommand, } -fn determine_file_format_from_name(s: &str) -> Option { +fn determine_input_file_format_from_name(s: &str) -> Option { if s.ends_with(".json") { - Some(TraceEventsFileFormat::Json) + Some(codetracer_trace_reader::TraceEventsFileFormat::Json) } else if s.ends_with(".bin") { - Some(TraceEventsFileFormat::Binary) + Some(codetracer_trace_reader::TraceEventsFileFormat::Binary) + } else { + None + } +} + +fn determine_output_file_format_from_name(s: &str) -> Option { + if s.ends_with(".json") { + Some(codetracer_trace_writer::TraceEventsFileFormat::Json) + } else if s.ends_with(".bin") { + Some(codetracer_trace_writer::TraceEventsFileFormat::Binary) } else { None } @@ -42,8 +53,8 @@ fn main() { match args.command { 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 input_file_format = determine_input_file_format_from_name(&convert_command.input_file).unwrap(); + let output_file_format = determine_output_file_format_from_name(&convert_command.output_file).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(); diff --git a/runtime_tracing/tests/binary_format.rs b/codetracer_trace_util/tests/binary_format.rs similarity index 57% rename from runtime_tracing/tests/binary_format.rs rename to codetracer_trace_util/tests/binary_format.rs index e4804f8..a03622b 100644 --- a/runtime_tracing/tests/binary_format.rs +++ b/codetracer_trace_util/tests/binary_format.rs @@ -1,11 +1,14 @@ -use runtime_tracing::{TraceEventsFileFormat, TraceWriter, create_trace_reader, create_trace_writer}; use std::fs; use std::path::Path; -fn test_binary_roundtrip(ver: TraceEventsFileFormat, binfile: &str) { +use codetracer_trace_reader::create_trace_reader; +use codetracer_trace_writer::create_trace_writer; +use codetracer_trace_writer::trace_writer::TraceWriter; + +fn test_binary_roundtrip(ver: codetracer_trace_writer::TraceEventsFileFormat, binfile: &str) { let json_path = Path::new("tests/data/trace.json"); - let mut json_reader = create_trace_reader(TraceEventsFileFormat::Json); + let mut json_reader = create_trace_reader(codetracer_trace_reader::TraceEventsFileFormat::Json); let original = json_reader.load_trace_events(json_path).unwrap(); let bin_path_str = format!("tests/data/{}", binfile); @@ -16,7 +19,7 @@ fn test_binary_roundtrip(ver: TraceEventsFileFormat, binfile: &str) { TraceWriter::append_events(bin_writer.as_mut(), &mut original.clone()); bin_writer.finish_writing_trace_events().unwrap(); - let mut bin_reader = create_trace_reader(TraceEventsFileFormat::Binary); + let mut bin_reader = create_trace_reader(codetracer_trace_reader::TraceEventsFileFormat::Binary); let tracer2_events = bin_reader.load_trace_events(bin_path).unwrap(); fs::remove_file(bin_path).unwrap(); @@ -29,10 +32,10 @@ fn test_binary_roundtrip(ver: TraceEventsFileFormat, binfile: &str) { #[test] fn test_binary_roundtrip_v0() { - test_binary_roundtrip(TraceEventsFileFormat::BinaryV0, "trace.v0.bin"); + test_binary_roundtrip(codetracer_trace_writer::TraceEventsFileFormat::BinaryV0, "trace.v0.bin"); } #[test] fn test_binary_roundtrip_v1() { - test_binary_roundtrip(TraceEventsFileFormat::Binary, "trace.v1.bin"); + test_binary_roundtrip(codetracer_trace_writer::TraceEventsFileFormat::Binary, "trace.v1.bin"); } diff --git a/runtime_tracing/tests/data/trace.json b/codetracer_trace_util/tests/data/trace.json similarity index 100% rename from runtime_tracing/tests/data/trace.json rename to codetracer_trace_util/tests/data/trace.json diff --git a/codetracer_trace_writer/Cargo.toml b/codetracer_trace_writer/Cargo.toml new file mode 100644 index 0000000..8a1b6ba --- /dev/null +++ b/codetracer_trace_writer/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "codetracer_trace_writer" +version = "0.16.0" +edition = "2024" +authors = ["Metacraft Labs Ltd"] +description = "A library for writing the CodeTracer db trace format" +repository = "https://github.com/metacraft-labs/runtime_tracing" +license = "MIT" +keywords = ["debugging", "development-tools"] + +[dependencies] +codetracer_trace_types.workspace = true +codetracer_trace_format_capnp.workspace = true +codetracer_trace_format_cbor_zstd.workspace = true +serde_json = "1.0" +cbor4ii = { version = "1.0.0", features = ["serde1", "use_std"] } + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +zeekstd = "0.6.0" + +[target.'cfg(target_arch = "wasm32")'.dependencies] +ruzstd = "0.8.1" diff --git a/runtime_tracing/src/abstract_trace_writer.rs b/codetracer_trace_writer/src/abstract_trace_writer.rs similarity index 85% rename from runtime_tracing/src/abstract_trace_writer.rs rename to codetracer_trace_writer/src/abstract_trace_writer.rs index a93997b..7cac06f 100644 --- a/runtime_tracing/src/abstract_trace_writer.rs +++ b/codetracer_trace_writer/src/abstract_trace_writer.rs @@ -6,8 +6,11 @@ use std::{ path::{Path, PathBuf}, }; -use crate::{ - tracer::TOP_LEVEL_FUNCTION_ID, AssignCellRecord, AssignCompoundItemRecord, AssignmentRecord, CallRecord, CellValueRecord, CompoundValueRecord, FullValueRecord, FunctionId, FunctionRecord, Line, PathId, RValue, RecordEvent, ReturnRecord, StepRecord, ThreadId, TraceLowLevelEvent, TraceMetadata, TypeId, TypeKind, TypeRecord, TypeSpecificInfo, VariableCellRecord, VariableId, NONE_TYPE_ID +use codetracer_trace_types::{ + AssignCellRecord, AssignCompoundItemRecord, AssignmentRecord, BindVariableRecord, CallRecord, CellValueRecord, CompoundValueRecord, EventLogKind, + FullValueRecord, FunctionId, FunctionRecord, Line, NONE_TYPE_ID, PassBy, PathId, Place, RValue, RecordEvent, ReturnRecord, StepRecord, + TOP_LEVEL_FUNCTION_ID, ThreadId, TraceLowLevelEvent, TraceMetadata, TypeId, TypeKind, TypeRecord, TypeSpecificInfo, ValueRecord, + VariableCellRecord, VariableId, }; pub struct AbstractTraceWriterData { @@ -98,12 +101,12 @@ pub trait AbstractTraceWriter { *self.get_data().functions.get(function_name).unwrap() } - fn ensure_type_id(&mut self, kind: crate::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) } - fn ensure_raw_type_id(&mut self, typ: crate::TypeRecord) -> TypeId { + fn ensure_raw_type_id(&mut self, typ: TypeRecord) -> TypeId { if !self.get_data().types.contains_key(&typ.lang_type) { let mut_data = self.get_mut_data(); mut_data.types.insert(typ.lang_type.clone(), TypeId(mut_data.types.len())); @@ -141,7 +144,7 @@ pub trait AbstractTraceWriter { self.add_event(TraceLowLevelEvent::Step(StepRecord { path_id, line })); } - 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 @@ -159,16 +162,16 @@ pub trait AbstractTraceWriter { self.add_event(TraceLowLevelEvent::Call(CallRecord { function_id, args })); } - fn arg(&mut self, name: &str, value: crate::ValueRecord) -> FullValueRecord { + fn arg(&mut self, name: &str, value: ValueRecord) -> FullValueRecord { let variable_id = self.ensure_variable_id(name); FullValueRecord { variable_id, value } } - fn register_return(&mut self, return_value: crate::ValueRecord) { + fn register_return(&mut self, return_value: ValueRecord) { self.add_event(TraceLowLevelEvent::Return(ReturnRecord { return_value })); } - fn register_special_event(&mut self, kind: crate::EventLogKind, content: &str) { + fn register_special_event(&mut self, kind: EventLogKind, content: &str) { self.add_event(TraceLowLevelEvent::Event(RecordEvent { kind, metadata: "".to_string(), @@ -176,7 +179,7 @@ pub trait AbstractTraceWriter { })); } - fn to_raw_type(&self, kind: crate::TypeKind, lang_type: &str) -> crate::TypeRecord { + fn to_raw_type(&self, kind: TypeKind, lang_type: &str) -> TypeRecord { TypeRecord { kind, lang_type: lang_type.to_string(), @@ -184,12 +187,12 @@ pub trait AbstractTraceWriter { } } - fn register_type(&mut self, kind: crate::TypeKind, lang_type: &str) { + fn register_type(&mut self, kind: TypeKind, lang_type: &str) { let typ = self.to_raw_type(kind, lang_type); self.add_event(TraceLowLevelEvent::Type(typ)); } - fn register_raw_type(&mut self, typ: crate::TypeRecord) { + fn register_raw_type(&mut self, typ: TypeRecord) { self.add_event(TraceLowLevelEvent::Type(typ)); } @@ -197,7 +200,7 @@ pub trait AbstractTraceWriter { self.add_event(TraceLowLevelEvent::Asm(instructions.to_vec())); } - fn register_variable_with_full_value(&mut self, name: &str, value: crate::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); } @@ -206,19 +209,19 @@ pub trait AbstractTraceWriter { self.add_event(TraceLowLevelEvent::VariableName(variable_name.to_string())); } - fn register_full_value(&mut self, variable_id: VariableId, value: crate::ValueRecord) { + fn register_full_value(&mut self, variable_id: VariableId, value: ValueRecord) { self.add_event(TraceLowLevelEvent::Value(FullValueRecord { variable_id, value })); } - fn register_compound_value(&mut self, place: crate::Place, value: crate::ValueRecord) { + fn register_compound_value(&mut self, place: Place, value: ValueRecord) { self.add_event(TraceLowLevelEvent::CompoundValue(CompoundValueRecord { place, value })); } - fn register_cell_value(&mut self, place: crate::Place, value: crate::ValueRecord) { + fn register_cell_value(&mut self, place: Place, value: ValueRecord) { self.add_event(TraceLowLevelEvent::CellValue(CellValueRecord { place, value })); } - fn assign_compound_item(&mut self, place: crate::Place, index: usize, item_place: crate::Place) { + fn assign_compound_item(&mut self, place: Place, index: usize, item_place: Place) { self.add_event(TraceLowLevelEvent::AssignCompoundItem(AssignCompoundItemRecord { place, index, @@ -226,11 +229,11 @@ pub trait AbstractTraceWriter { })); } - fn assign_cell(&mut self, place: crate::Place, new_value: crate::ValueRecord) { + fn assign_cell(&mut self, place: Place, new_value: ValueRecord) { self.add_event(TraceLowLevelEvent::AssignCell(AssignCellRecord { place, new_value })); } - fn register_variable(&mut self, variable_name: &str, place: crate::Place) { + fn register_variable(&mut self, variable_name: &str, place: Place) { let variable_id = self.ensure_variable_id(variable_name); self.add_event(TraceLowLevelEvent::VariableCell(VariableCellRecord { variable_id, place })); } @@ -241,7 +244,7 @@ pub trait AbstractTraceWriter { } // history event helpers - fn assign(&mut self, variable_name: &str, rvalue: crate::RValue, pass_by: crate::PassBy) { + fn assign(&mut self, variable_name: &str, rvalue: RValue, pass_by: PassBy) { let variable_id = self.ensure_variable_id(variable_name); self.add_event(TraceLowLevelEvent::Assignment(AssignmentRecord { to: variable_id, @@ -250,9 +253,9 @@ pub trait AbstractTraceWriter { })); } - fn bind_variable(&mut self, variable_name: &str, place: crate::Place) { + fn bind_variable(&mut self, variable_name: &str, place: Place) { let variable_id = self.ensure_variable_id(variable_name); - self.add_event(TraceLowLevelEvent::BindVariable(crate::BindVariableRecord { variable_id, place })); + self.add_event(TraceLowLevelEvent::BindVariable(BindVariableRecord { variable_id, place })); } fn drop_variables(&mut self, variable_names: &[String]) { @@ -264,12 +267,12 @@ pub trait AbstractTraceWriter { self.add_event(TraceLowLevelEvent::DropVariables(variable_ids)) } - fn simple_rvalue(&mut self, variable_name: &str) -> crate::RValue { + fn simple_rvalue(&mut self, variable_name: &str) -> RValue { let variable_id = self.ensure_variable_id(variable_name); RValue::Simple(variable_id) } - fn compound_rvalue(&mut self, variable_dependencies: &[String]) -> crate::RValue { + fn compound_rvalue(&mut self, variable_dependencies: &[String]) -> RValue { let variable_ids: Vec = variable_dependencies .to_vec() .iter() diff --git a/runtime_tracing/src/cbor_zstd_writer.rs b/codetracer_trace_writer/src/cbor_zstd_writer.rs similarity index 83% rename from runtime_tracing/src/cbor_zstd_writer.rs rename to codetracer_trace_writer/src/cbor_zstd_writer.rs index 8681fc9..6d0a4d8 100644 --- a/runtime_tracing/src/cbor_zstd_writer.rs +++ b/codetracer_trace_writer/src/cbor_zstd_writer.rs @@ -1,20 +1,13 @@ use std::{fs::File, io::Write, path::PathBuf}; +use codetracer_trace_format_cbor_zstd::HEADERV1; use zeekstd::Encoder; use crate::{ abstract_trace_writer::{AbstractTraceWriter, AbstractTraceWriterData}, trace_writer::TraceWriter, - TraceLowLevelEvent, }; - -/// The next 3 bytes are reserved/version info. -/// The header is 8 bytes in size, ensuring 64-bit alignment for the rest of the file. -pub const HEADERV1: &[u8] = &[ - 0xC0, 0xDE, 0x72, 0xAC, 0xE2, // The first 5 bytes identify the file as a CodeTracer file (hex l33tsp33k - C0DE72ACE2 for "CodeTracer"). - 0x01, // Indicates version 1 of the file format - 0x00, 0x00, -]; // Reserved, must be zero in this version. +use codetracer_trace_types::TraceLowLevelEvent; pub struct CborZstdTraceWriter<'a> { base: AbstractTraceWriterData, diff --git a/runtime_tracing/src/cbor_zstd_writer_wasm.rs b/codetracer_trace_writer/src/cbor_zstd_writer_wasm.rs similarity index 84% rename from runtime_tracing/src/cbor_zstd_writer_wasm.rs rename to codetracer_trace_writer/src/cbor_zstd_writer_wasm.rs index 084f1f6..5cdd8fe 100644 --- a/runtime_tracing/src/cbor_zstd_writer_wasm.rs +++ b/codetracer_trace_writer/src/cbor_zstd_writer_wasm.rs @@ -7,18 +7,11 @@ use std::{ use ruzstd::encoding::{CompressionLevel, compress}; use crate::{ - TraceLowLevelEvent, abstract_trace_writer::{AbstractTraceWriter, AbstractTraceWriterData}, trace_writer::TraceWriter, }; - -/// The next 3 bytes are reserved/version info. -/// The header is 8 bytes in size, ensuring 64-bit alignment for the rest of the file. -pub const HEADERV1: &[u8] = &[ - 0xC0, 0xDE, 0x72, 0xAC, 0xE2, // The first 5 bytes identify the file as a CodeTracer file (hex l33tsp33k - C0DE72ACE2 for "CodeTracer"). - 0x01, // Indicates version 1 of the file format - 0x00, 0x00, -]; // Reserved, must be zero in this version. +use codetracer_trace_types::TraceLowLevelEvent; +use codetracer_trace_format_cbor_zstd::HEADERV1; pub struct CborZstdTraceWriter { base: AbstractTraceWriterData, diff --git a/runtime_tracing/src/lib.rs b/codetracer_trace_writer/src/lib.rs similarity index 80% rename from runtime_tracing/src/lib.rs rename to codetracer_trace_writer/src/lib.rs index 04d8a9a..9954a69 100644 --- a/runtime_tracing/src/lib.rs +++ b/codetracer_trace_writer/src/lib.rs @@ -1,50 +1,37 @@ -// allow it, because I am not sure we need it? -// better to explicitly turn into the newtype types -// but i might be wrong -// also for now, allowing it to pass `cargo clippy` -#![allow(clippy::from_over_into)] -//! Runtime tracing structures and helpers for the CodeTracer debugger. -//! -//! 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 abstract_trace_writer; -mod base64; -mod capnptrace; +mod non_streaming_trace_writer; +pub mod trace_writer; -#[cfg(target_arch = "wasm32")] -#[path = "./cbor_zstd_reader_wasm.rs"] -mod cbor_zstd_reader; #[cfg(target_arch = "wasm32")] #[path = "./cbor_zstd_writer_wasm.rs"] mod cbor_zstd_writer; -#[cfg(not(target_arch = "wasm32"))] -mod cbor_zstd_reader; #[cfg(not(target_arch = "wasm32"))] mod cbor_zstd_writer; -mod non_streaming_trace_writer; -mod trace_readers; -mod trace_writer; -mod tracer; -mod types; - -pub use crate::non_streaming_trace_writer::NonStreamingTraceWriter; -pub use crate::trace_readers::TraceReader; -pub use crate::trace_writer::TraceWriter; -pub use crate::tracer::{NONE_TYPE_ID, NONE_VALUE, TraceEventsFileFormat, create_trace_reader, create_trace_writer}; -pub use crate::types::*; - -pub mod trace_capnp { - include!(concat!(env!("OUT_DIR"), "/src/trace_capnp.rs")); +#[derive(Debug, Clone, Copy)] +pub enum TraceEventsFileFormat { + Json, + BinaryV0, + Binary, +} + +pub fn create_trace_writer(program: &str, args: &[String], format: TraceEventsFileFormat) -> Box { + match format { + TraceEventsFileFormat::Json | TraceEventsFileFormat::BinaryV0 => { + let mut result = Box::new(non_streaming_trace_writer::NonStreamingTraceWriter::new(program, args)); + result.set_format(format); + result + } + TraceEventsFileFormat::Binary => Box::new(crate::cbor_zstd_writer::CborZstdTraceWriter::new(program, args)), + } } #[cfg(test)] mod tests { - use super::*; + use codetracer_trace_types::*; use std::path::Path; - // use std::path::PathBuf; + use crate::{non_streaming_trace_writer::NonStreamingTraceWriter, trace_writer::TraceWriter}; #[test] fn test_simple_trace() { @@ -172,14 +159,4 @@ mod tests { // tracer.store_trace_paths(&PathBuf::from("trace_paths.json")).unwrap(); // tracer.store_trace_events(&PathBuf::from("trace.json")).unwrap(); } - - #[test] - fn test_equality_of_value_records() { - let a = ValueRecord::Int { i: 0, type_id: TypeId(0) }; // just an example type_id - let b = ValueRecord::Int { i: 0, type_id: TypeId(0) }; - let different = ValueRecord::Int { i: 1, type_id: TypeId(0) }; - - assert_eq!(a, b); - assert_ne!(a, different); - } } diff --git a/runtime_tracing/src/non_streaming_trace_writer.rs b/codetracer_trace_writer/src/non_streaming_trace_writer.rs similarity index 92% rename from runtime_tracing/src/non_streaming_trace_writer.rs rename to codetracer_trace_writer/src/non_streaming_trace_writer.rs index 5a00c77..a36f865 100644 --- a/runtime_tracing/src/non_streaming_trace_writer.rs +++ b/codetracer_trace_writer/src/non_streaming_trace_writer.rs @@ -5,9 +5,11 @@ use std::{ }; use crate::{ - TraceEventsFileFormat, TraceLowLevelEvent, TraceWriter, + TraceEventsFileFormat, trace_writer::TraceWriter, abstract_trace_writer::{AbstractTraceWriter, AbstractTraceWriterData}, }; +use codetracer_trace_format_capnp::capnptrace::write_trace; +use codetracer_trace_types::TraceLowLevelEvent; /// State machine used to record [`TraceLowLevelEvent`]s. /// @@ -75,7 +77,7 @@ impl TraceWriter for NonStreamingTraceWriter { } TraceEventsFileFormat::BinaryV0 => { let mut file = fs::File::create(path)?; - crate::capnptrace::write_trace(&self.events, &mut file)?; + write_trace(&self.events, &mut file)?; } TraceEventsFileFormat::Binary => { unreachable!() diff --git a/runtime_tracing/src/trace_writer.rs b/codetracer_trace_writer/src/trace_writer.rs similarity index 98% rename from runtime_tracing/src/trace_writer.rs rename to codetracer_trace_writer/src/trace_writer.rs index 748f92b..758a8a0 100644 --- a/runtime_tracing/src/trace_writer.rs +++ b/codetracer_trace_writer/src/trace_writer.rs @@ -1,8 +1,9 @@ use std::{error::Error, path::Path}; -use crate::{ +use crate::abstract_trace_writer::AbstractTraceWriter; +use codetracer_trace_types::{ EventLogKind, FullValueRecord, FunctionId, Line, PassBy, PathId, Place, RValue, TraceLowLevelEvent, TypeId, TypeKind, TypeRecord, ValueRecord, - VariableId, abstract_trace_writer::AbstractTraceWriter, + VariableId, }; pub trait TraceWriter: AbstractTraceWriter { diff --git a/runtime_tracing/Cargo.toml b/runtime_tracing/Cargo.toml deleted file mode 100644 index 852ef51..0000000 --- a/runtime_tracing/Cargo.toml +++ /dev/null @@ -1,38 +0,0 @@ -[package] -name = "runtime_tracing" -version = "0.15.0" -edition = "2024" -authors = ["Metacraft Labs Ltd"] -description = "A library for the schema and tracing helpers for the CodeTracer db trace format" -readme = "README.md" -repository = "https://github.com/metacraft-labs/runtime_tracing" -license = "MIT" -keywords = ["debugging", "development-tools"] -build = "build.rs" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -base64 = "0.22.1" -num-traits = "0.2" -num-derive = "0.4" -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" -serde_repr = "0.1" -schemars = "0.8.2" -capnp = "0.21.1" -cbor4ii = { version = "1.0.0", features = ["serde1", "use_std"] } -fscommon = "0.1.1" - -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] -zeekstd = "0.6.0" - -[target.'cfg(target_arch = "wasm32")'.dependencies] -ruzstd = "0.8.1" - -[build-dependencies] -capnpc = "0.21.0" - -[lib] -name = "runtime_tracing" -path = "src/lib.rs" diff --git a/runtime_tracing/README.md b/runtime_tracing/README.md deleted file mode 100644 index befff32..0000000 --- a/runtime_tracing/README.md +++ /dev/null @@ -1,69 +0,0 @@ -## runtime_tracing - -A format and helper library for [CodeTracer](https://github.com/metacraft-labs/CodeTracer.git) traces - -### format - -A CodeTracer trace for its db backend consists of record data, metadata for the recorded program and copy of the relevant source/repository files. -It's self contained, so one can debug a record of a version of a program from a different commit or branch. -The record data consists of a stream of objects, each of which describes a certain program event: call, step, return etc. - -A trace contains several files: -* `trace.json` – the event data in JSON format -* `trace.bin` – the same event stream encoded in a binary format (see - [docs/trace_binary_spec.md](docs/trace_binary_spec.md)) -* `trace_metadata.json` – metadata for the recorded program -* `trace_paths.json` – a list of the recorded files -* `files/` – a folder including all the source/repository files copied into the trace. - -The event stream can be stored either as JSON (`trace.json`) or in the -binary format (`trace.bin`). Both representations correspond to the Rust -types in `src/types.rs`. - -We plan on -* defining a more precise document or a list of examples or a specification. -* producing a more optimized version of the format. A binary variant is now - available as `trace.bin`. - -A future goal of this format is to make it possible to stream traces: to be able to replay them while they're still being recorded. -This is one of the reasons for the decision to maintain a single "stream" of events currently. - -### tracer library - -We also define a Rust tracer library in `src/tracer.rs` which can be used as a helper to instrument Rust-based language interpreters and vm-s. -It can make it easier to migrate to newer versions of the format, hiding many details behind its helpers. -There are a few examples and tests of its usage in `src/lib.rs`. - -There are some actual usages of it as well which can be also used as an example: -* in [blocksense-network/noir: their tracing support for CodeTracer](https://github.com/blocksense-network/noir/tree/blocksense/tooling/tracer) -* in a small toy interpreter to be released as a part of the CodeTracer repo - -One can always directly produce the same traces from various languages. We're open for cooperation or discussion on usecases! - -### Building the Documentation - -The library API docs can be built locally with: - -```bash -cargo doc --all-features --no-deps -``` - -The generated HTML documentation will be placed under `target/doc`. Open -`target/doc/runtime_tracing/index.html` in a browser to inspect it. - -### Publishing to crates.io - -After updating the version number in `Cargo.toml`, publish a new release with: - -```bash -cargo publish -``` - -Documentation for released versions will be automatically hosted on -[docs.rs](https://docs.rs/runtime_tracing). - -### Legal - -Authored and maintained by Metacraft Labs, Ltd - -LICENSE: MIT diff --git a/runtime_tracing/src/tracer.rs b/runtime_tracing/src/tracer.rs deleted file mode 100644 index 49c4233..0000000 --- a/runtime_tracing/src/tracer.rs +++ /dev/null @@ -1,42 +0,0 @@ -//! Helper for generating trace events from a running program or interpreter. - -use crate::TraceWriter; -use crate::non_streaming_trace_writer::NonStreamingTraceWriter; -use crate::trace_readers::{BinaryTraceReader, JsonTraceReader, TraceReader}; -use crate::types::{FunctionId, TypeId, ValueRecord}; - -#[derive(Debug, Clone, Copy)] -pub enum TraceEventsFileFormat { - Json, - BinaryV0, - Binary, -} - -// we ensure in start they are registered with those id-s - -// pub const EXAMPLE_INT_TYPE_ID: TypeId = TypeId(0); -// pub const EXAMPLE_FLOAT_TYPE_ID: TypeId = TypeId(1); -// pub const EXAMPLE_BOOL_TYPE_ID: TypeId = TypeId(2); -// pub const EXAMPLE_STRING_TYPE_ID: TypeId = TypeId(3); -pub const NONE_TYPE_ID: TypeId = TypeId(0); -pub const NONE_VALUE: ValueRecord = ValueRecord::None { type_id: NONE_TYPE_ID }; - -pub const TOP_LEVEL_FUNCTION_ID: FunctionId = FunctionId(0); - -pub fn create_trace_reader(format: TraceEventsFileFormat) -> Box { - match format { - TraceEventsFileFormat::Json => Box::new(JsonTraceReader {}), - TraceEventsFileFormat::BinaryV0 | TraceEventsFileFormat::Binary => Box::new(BinaryTraceReader {}), - } -} - -pub fn create_trace_writer(program: &str, args: &[String], format: TraceEventsFileFormat) -> Box { - match format { - TraceEventsFileFormat::Json | TraceEventsFileFormat::BinaryV0 => { - let mut result = Box::new(NonStreamingTraceWriter::new(program, args)); - result.set_format(format); - result - } - TraceEventsFileFormat::Binary => Box::new(crate::cbor_zstd_writer::CborZstdTraceWriter::new(program, args)), - } -}