Skip to content

Commit

Permalink
1.77.0
Browse files Browse the repository at this point in the history
  • Loading branch information
billy1624 committed Mar 28, 2024
1 parent 5f6ba88 commit 0392c15
Show file tree
Hide file tree
Showing 21 changed files with 545 additions and 37 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# Changelog

## 1.76.1 - Pending
## 1.77.0 - 2024-03-28

### Versions

+ `1.77.0-beta.1`: 2024-03-25

### New Features

- debugger: trace allocations (Box, Arc, Rc)

Expand Down
6 changes: 3 additions & 3 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion command/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "firedbg-cli"
version = "1.76.0"
version = "1.77.0"
edition = "2021"
license = "MIT OR Apache-2.0"
authors = [
Expand Down
2 changes: 1 addition & 1 deletion debugger/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "firedbg-rust-debugger"
version = "1.76.0"
version = "1.77.0"
edition = "2021"
license = "MIT OR Apache-2.0"
build = "build.rs"
Expand Down
4 changes: 3 additions & 1 deletion debugger/src/debugger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -722,7 +722,9 @@ fn run(mut params: DebuggerParams, mut producer: SeaProducer) -> Result<()> {
})
.iter()
{
write_variable(var);
if var.name().is_some() {
write_variable(var);
}
}
}
VariableCapture::Only(vars) => {
Expand Down
72 changes: 53 additions & 19 deletions debugger/src/debugger/return_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -599,23 +599,47 @@ pub(super) fn write_return_value(
None
};
event.write_option(rwriter, RETVAL, return_type.name(), value);
} else if matches!(left, ValueType::i128 | ValueType::u128) {
let val = {
#[cfg(target_arch = "x86_64")]
{
let rdx_u64 = read_u64(&rdx())?;
let rcx_u64 = read_u64(&rcx())?;
let res_is_rcx = (rdx_u64 == 0 && rcx_u64 == 1)
|| (rdx_u64 == 0 && rcx_u64 == 0);
if res_is_rcx && (read_u64(&rdx())? & 0xF) != 0 {
let v = {
let v = [reg("rsi"), reg("r8")];
&values_to_bytes::<16, _>(v.into_iter(), 2)?
};
Some(rwriter.prim_v(left.primitive_name(), v))
} else if !res_is_rcx && (read_u64(&rdx())? & 0xF) != 0 {
let v = {
let v = [reg("rdi"), reg("r8")];
&values_to_bytes::<16, _>(v.into_iter(), 2)?
};
Some(rwriter.prim_v(left.primitive_name(), v))
} else {
None
}
}
#[cfg(target_arch = "aarch64")]
{
if opt != 0 {
let v = {
let v = [reg("x2"), reg("x3")];
&values_to_bytes::<16, _>(v.into_iter(), 2)?
};
Some(rwriter.prim_v(left.primitive_name(), v))
} else {
None
}
}
};
event.write_option(rwriter, RETVAL, return_type.name(), val);
} else if opt != 0 {
let val = if left_size == 0 {
rwriter.unit_v()
} else if matches!(left, ValueType::i128 | ValueType::u128) {
let v = {
#[cfg(target_arch = "x86_64")]
{
// we are using rcx too
&values_to_bytes::<16, _>([rdx(), rcx()].into_iter(), 2)?
}
#[cfg(target_arch = "aarch64")]
{
let v = [reg("x2"), reg("x3")];
&values_to_bytes::<16, _>(v.into_iter(), 2)?
}
};
rwriter.prim_v(left.primitive_name(), v)
} else if matches!(left, ValueType::Slice(_)) {
get_slice_from_rax_rdx(rwriter, &left, &left_type)?
} else if left.is_thin_ptr() {
Expand Down Expand Up @@ -793,17 +817,27 @@ pub(super) fn write_return_value(
{
// Result<i128, i128>, Result<u128, u128>, Result<i128, ()>, Result<(), u128>
log::trace!("{} rcx, rdx", return_type.name());
let res = read_u64(&rax())?;
let v = {
let (res, v) = {
#[cfg(target_arch = "x86_64")]
{
// we are using rcx too
&values_to_bytes::<16, _>([rdx(), rcx()].into_iter(), 2)?
let rdx_u64 = read_u64(&rdx())?;
let rcx_u64 = read_u64(&rcx())?;
let res_is_rcx = (rdx_u64 == 0 && rcx_u64 == 1)
|| (rdx_u64 == 0 && rcx_u64 == 0);
let has_unit = left_size == 0 || right_size == 0;
let res = if res_is_rcx { rcx_u64 } else { rdx_u64 };
let v = if res_is_rcx {
[reg("rsi"), reg("r8")]
} else {
[reg("rdi"), reg("r8")]
};
(res, &values_to_bytes::<16, _>(v.into_iter(), 2)?)
}
#[cfg(target_arch = "aarch64")]
{
let res = read_u64(&rax())?;
let v = [reg("x2"), reg("x3")];
&values_to_bytes::<16, _>(v.into_iter(), 2)?
(res, &values_to_bytes::<16, _>(v.into_iter(), 2)?)
}
};
let val = if left_size == 0 && res == 0 {
Expand Down
89 changes: 89 additions & 0 deletions debugger/tests/async-1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
mod util;
use util::*;

use anyhow::Result;
use firedbg_rust_debugger::{Bytes, Debugger, Event, EventStream};
use pretty_assertions::assert_eq;
use sea_streamer::{Buffer, Consumer, Message, Producer};

#[tokio::test]
async fn main() -> Result<()> {
let testcase = "async-1";
let (producer, consumer) = setup(testcase).await?;

let mut debugger_params = debugger_params_testbench(testcase);

println!("{:#?}", debugger_params.breakpoints);

Debugger::run(debugger_params, producer.clone());

producer.end().await?;

for i in 0..100 {
let payload = consumer.next().await?.message().into_bytes();
let event = EventStream::read_from(Bytes::from(payload));
println!("#{i} {:?}", event);

match &event {
Event::Breakpoint { .. } => (),
Event::FunctionCall { function_name, .. } => {}
Event::FunctionReturn { function_name, .. } => {}
}
}

Ok(())
}

// function end }
// 1. without {{closure}}: enter future
// 2. with {{closure}}: exit future
//
// function {
// 1. everytime future is re-entered

// #0 FunctionCall { breakpoint_id: 9, thread_id: 12475492, frame_id: 1, stack_pointer: 6123578480, function_name: "main::main", arguments: [] }
// #1 FunctionCall { breakpoint_id: 5, thread_id: 12475492, frame_id: 2, stack_pointer: 6123573392, function_name: "main::uid", arguments: [] }
// #2 FunctionReturn { breakpoint_id: 29, thread_id: 12475492, frame_id: 2, function_name: "main::uid", return_value: Prim(u64(5581)) }
// #3 FunctionCall { breakpoint_id: 7, thread_id: 12475492, frame_id: 3, stack_pointer: 6123573408, function_name: "main::sleep2", arguments: [("ctx", Prim(u64(5581)))] }
// #4 FunctionReturn { breakpoint_id: 30, thread_id: 12475492, frame_id: 3, function_name: "main::sleep2", return_value: Opaque }
// #5 FunctionCall { breakpoint_id: 8, thread_id: 12475492, frame_id: 4, stack_pointer: 6123573408, function_name: "main::sleep3", arguments: [("ctx", Prim(u64(5581)))] }
// #6 FunctionReturn { breakpoint_id: 31, thread_id: 12475492, frame_id: 4, function_name: "main::sleep3", return_value: Opaque }
// #7 FunctionCall { breakpoint_id: 7, thread_id: 12475492, frame_id: 5, stack_pointer: 6123571040, function_name: "main::sleep2::{{closure}}", arguments: [] }
// #8 FunctionCall { breakpoint_id: 5, thread_id: 12475492, frame_id: 6, stack_pointer: 6123571008, function_name: "main::uid", arguments: [] }
// #9 FunctionReturn { breakpoint_id: 29, thread_id: 12475492, frame_id: 6, function_name: "main::uid", return_value: Prim(u64(6411)) }
// #10 FunctionCall { breakpoint_id: 6, thread_id: 12475492, frame_id: 7, stack_pointer: 6123571024, function_name: "main::sleeper", arguments: [("ctx", Prim(u64(6411))), ("i", Prim(u64(1)))] }
// #11 FunctionReturn { breakpoint_id: 35, thread_id: 12475492, frame_id: 7, function_name: "main::sleeper", return_value: Opaque }
// #12 FunctionCall { breakpoint_id: 6, thread_id: 12475492, frame_id: 8, stack_pointer: 6123570160, function_name: "main::sleeper::{{closure}}", arguments: [] }
// #13 FunctionCall { breakpoint_id: 5, thread_id: 12475492, frame_id: 9, stack_pointer: 6123570128, function_name: "main::uid", arguments: [] }
// #14 FunctionReturn { breakpoint_id: 29, thread_id: 12475492, frame_id: 9, function_name: "main::uid", return_value: Prim(u64(3181)) }
// #15 FunctionReturn { breakpoint_id: 36, thread_id: 12475492, frame_id: 8, function_name: "main::sleeper::{{closure}}", return_value: Opaque }
// #16 FunctionReturn { breakpoint_id: 32, thread_id: 12475492, frame_id: 5, function_name: "main::sleep2::{{closure}}", return_value: Opaque }
// #17 FunctionCall { breakpoint_id: 8, thread_id: 12475492, frame_id: 10, stack_pointer: 6123571584, function_name: "main::sleep3::{{closure}}", arguments: [] }
// #18 FunctionCall { breakpoint_id: 5, thread_id: 12475492, frame_id: 11, stack_pointer: 6123571552, function_name: "main::uid", arguments: [] }
// #19 FunctionReturn { breakpoint_id: 29, thread_id: 12475492, frame_id: 11, function_name: "main::uid", return_value: Prim(u64(3079)) }
// #20 FunctionCall { breakpoint_id: 6, thread_id: 12475492, frame_id: 12, stack_pointer: 6123571568, function_name: "main::sleeper", arguments: [("ctx", Prim(u64(3079))), ("i", Prim(u64(3)))] }
// #21 FunctionReturn { breakpoint_id: 35, thread_id: 12475492, frame_id: 12, function_name: "main::sleeper", return_value: Opaque }
// #22 FunctionCall { breakpoint_id: 6, thread_id: 12475492, frame_id: 13, stack_pointer: 6123570704, function_name: "main::sleeper::{{closure}}", arguments: [] }
// #23 FunctionCall { breakpoint_id: 5, thread_id: 12475492, frame_id: 14, stack_pointer: 6123570672, function_name: "main::uid", arguments: [] }
// #24 FunctionReturn { breakpoint_id: 29, thread_id: 12475492, frame_id: 14, function_name: "main::uid", return_value: Prim(u64(9970)) }
// #25 FunctionReturn { breakpoint_id: 36, thread_id: 12475492, frame_id: 13, function_name: "main::sleeper::{{closure}}", return_value: Opaque }
// #26 FunctionReturn { breakpoint_id: 38, thread_id: 12475492, frame_id: 10, function_name: "main::sleep3::{{closure}}", return_value: Opaque }
// #27 FunctionCall { breakpoint_id: 8, thread_id: 12475492, frame_id: 15, stack_pointer: 6123571584, function_name: "main::sleep3::{{closure}}", arguments: [] }
// #28 FunctionCall { breakpoint_id: 6, thread_id: 12475492, frame_id: 16, stack_pointer: 6123570704, function_name: "main::sleeper::{{closure}}", arguments: [] }
// #29 FunctionReturn { breakpoint_id: 37, thread_id: 12475492, frame_id: 16, function_name: "main::sleeper::{{closure}}", return_value: Opaque }
// #30 FunctionReturn { breakpoint_id: 39, thread_id: 12475492, frame_id: 15, function_name: "main::sleep3::{{closure}}", return_value: Opaque }
// #31 FunctionCall { breakpoint_id: 7, thread_id: 12475492, frame_id: 17, stack_pointer: 6123571040, function_name: "main::sleep2::{{closure}}", arguments: [] }
// #32 FunctionCall { breakpoint_id: 6, thread_id: 12475492, frame_id: 18, stack_pointer: 6123570160, function_name: "main::sleeper::{{closure}}", arguments: [] }
// #33 FunctionReturn { breakpoint_id: 37, thread_id: 12475492, frame_id: 18, function_name: "main::sleeper::{{closure}}", return_value: Opaque }
// #34 FunctionCall { breakpoint_id: 6, thread_id: 12475492, frame_id: 19, stack_pointer: 6123571024, function_name: "main::sleeper", arguments: [("ctx", Prim(u64(6411))), ("i", Prim(u64(1)))] }
// #35 FunctionReturn { breakpoint_id: 35, thread_id: 12475492, frame_id: 19, function_name: "main::sleeper", return_value: Opaque }
// #36 FunctionCall { breakpoint_id: 6, thread_id: 12475492, frame_id: 20, stack_pointer: 6123570160, function_name: "main::sleeper::{{closure}}", arguments: [] }
// #37 FunctionCall { breakpoint_id: 5, thread_id: 12475492, frame_id: 21, stack_pointer: 6123570128, function_name: "main::uid", arguments: [] }
// #38 FunctionReturn { breakpoint_id: 29, thread_id: 12475492, frame_id: 21, function_name: "main::uid", return_value: Prim(u64(1054)) }
// #39 FunctionReturn { breakpoint_id: 36, thread_id: 12475492, frame_id: 20, function_name: "main::sleeper::{{closure}}", return_value: Opaque }
// #40 FunctionReturn { breakpoint_id: 33, thread_id: 12475492, frame_id: 17, function_name: "main::sleep2::{{closure}}", return_value: Opaque }
// #41 FunctionCall { breakpoint_id: 7, thread_id: 12475492, frame_id: 22, stack_pointer: 6123571040, function_name: "main::sleep2::{{closure}}", arguments: [] }
// #42 FunctionCall { breakpoint_id: 6, thread_id: 12475492, frame_id: 23, stack_pointer: 6123570160, function_name: "main::sleeper::{{closure}}", arguments: [] }
// #43 FunctionReturn { breakpoint_id: 37, thread_id: 12475492, frame_id: 23, function_name: "main::sleeper::{{closure}}", return_value: Opaque }
// #44 FunctionReturn { breakpoint_id: 34, thread_id: 12475492, frame_id: 22, function_name: "main::sleep2::{{closure}}", return_value: Opaque }
// #45 FunctionReturn { breakpoint_id: 10, thread_id: 12475492, frame_id: 1, function_name: "main::main", return_value: Unit }
26 changes: 26 additions & 0 deletions debugger/tests/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use std::{
fs::{File, OpenOptions},
io::Write,
path::Path,
time::SystemTime,
};

#[derive(Debug)]
Expand Down Expand Up @@ -52,6 +53,31 @@ pub fn debugger_params_from_file(testcase: &str) -> DebuggerParams {
}
}

pub fn debugger_params_testbench(testcase: &str) -> DebuggerParams {
let path = format!("../testbench/{testcase}/src/bin/main.rs");
let mut files = vec![Default::default()];
files.push(SourceFile {
id: 1,
path: path.clone(),
crate_name: testcase.into(),
modified: SystemTime::UNIX_EPOCH,
});

let mut breakpoints = vec![Default::default()];
for func in firedbg_rust_parser::parse_file(&path).unwrap() {
breakpoints.push(new_breakpoint(breakpoints.len() as u32, 1, func));
}

// TODO cargo b --bin main

DebuggerParams {
binary: format!("../testbench/{testcase}/target/debug/main"),
files,
breakpoints,
arguments: vec![],
}
}

pub fn generate_rust_program(testcase: &str, content: &str) -> DebuggerParams {
let path = format!("testcases/generated/{testcase}");
let src = format!("{path}.rs");
Expand Down
4 changes: 2 additions & 2 deletions indexer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "firedbg-stream-indexer"
version = "1.76.0"
version = "1.77.0"
edition = "2021"
license = "MIT OR Apache-2.0"
authors = [
Expand Down Expand Up @@ -28,7 +28,7 @@ tokio = { version = "1", optional = true }
pretty_assertions = { version = "1", optional = true }
async-trait = { version = "0.1", optional = true }
# workspace
firedbg-rust-debugger = { path = "../debugger", version = "1.76.0", default-features = false }
firedbg-rust-debugger = { path = "../debugger", version = "1.77.0", default-features = false }

[features]
# The base feature only exports the sea-orm entities
Expand Down
5 changes: 3 additions & 2 deletions indexer/src/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use crate::{
Processor,
};
use firedbg_rust_debugger::{
Breakpoint, Event, EventStream, InfoMessage, SourceFile, BREAKPOINT_STREAM, EVENT_STREAM,
FILE_STREAM, INFO_STREAM,
Breakpoint, Event, EventStream, InfoMessage, SourceFile, ALLOCATION_STREAM, BREAKPOINT_STREAM,
EVENT_STREAM, FILE_STREAM, INFO_STREAM,
};

#[derive(Debug, Default, Serialize, Deserialize)]
Expand Down Expand Up @@ -57,6 +57,7 @@ impl Processor for Validator {
event.redacted();
self.data.events.push(event);
}
ALLOCATION_STREAM => {}
_ => anyhow::bail!("Unexpected stream key {}", message.stream_key()),
}
}
Expand Down
1 change: 1 addition & 0 deletions parser/src/def/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize};
pub struct FunctionDef {
pub ty: FunctionType,
pub loc: BreakableSpan,
pub end: LineColumn,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
Expand Down
14 changes: 10 additions & 4 deletions parser/src/parsing/function.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::{parsing::parse_body_loc, FunctionDef, FunctionType};
use crate::{
parsing::{parse_body_end, parse_body_loc},
FunctionDef, FunctionType,
};
use syn::__private::ToTokens;

// Parse function breakpoints
Expand Down Expand Up @@ -35,7 +38,8 @@ impl ParseFunction for syn::ItemFn {
return_type,
};
let loc = parse_body_loc(&self.block);
let parent_breakpoint = FunctionDef { ty, loc };
let end = parse_body_end(&self.block);
let parent_breakpoint = FunctionDef { ty, loc, end };
parse_nested_func(parent_breakpoint, &self.block)
}
}
Expand Down Expand Up @@ -84,7 +88,8 @@ impl ParseFunction for (&syn::ItemImpl, &syn::ImplItemFn) {
},
};
let loc = parse_body_loc(&impl_item_fn.block);
let parent_breakpoint = FunctionDef { ty, loc };
let end = parse_body_end(&impl_item_fn.block);
let parent_breakpoint = FunctionDef { ty, loc, end };
parse_nested_func(parent_breakpoint, &impl_item_fn.block)
}
}
Expand Down Expand Up @@ -124,7 +129,8 @@ impl ParseFunction for (&syn::ItemTrait, &syn::TraitItemFn) {
return_type,
};
let loc = parse_body_loc(block);
let parent_breakpoint = FunctionDef { ty, loc };
let end = parse_body_end(block);
let parent_breakpoint = FunctionDef { ty, loc, end };
parse_nested_func(parent_breakpoint, block)
}
None => Vec::new(),
Expand Down
4 changes: 4 additions & 0 deletions parser/src/parsing/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ pub(crate) fn parse_body_loc(block: &syn::Block) -> BreakableSpan {
}
}

pub(crate) fn parse_body_end(block: &syn::Block) -> LineColumn {
block.span().end().into_loc()
}

/// Parse the line and column number of function block.
///
/// A function block is wrapped in a pair of braces, i.e. `{ ... }`
Expand Down
Loading

0 comments on commit 0392c15

Please sign in to comment.