Skip to content

Commit 0392c15

Browse files
committed
1.77.0
1 parent 5f6ba88 commit 0392c15

21 files changed

+545
-37
lines changed

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
# Changelog
22

3-
## 1.76.1 - Pending
3+
## 1.77.0 - 2024-03-28
4+
5+
### Versions
6+
7+
+ `1.77.0-beta.1`: 2024-03-25
8+
9+
### New Features
410

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

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

command/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "firedbg-cli"
3-
version = "1.76.0"
3+
version = "1.77.0"
44
edition = "2021"
55
license = "MIT OR Apache-2.0"
66
authors = [

debugger/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "firedbg-rust-debugger"
3-
version = "1.76.0"
3+
version = "1.77.0"
44
edition = "2021"
55
license = "MIT OR Apache-2.0"
66
build = "build.rs"

debugger/src/debugger.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,9 @@ fn run(mut params: DebuggerParams, mut producer: SeaProducer) -> Result<()> {
722722
})
723723
.iter()
724724
{
725-
write_variable(var);
725+
if var.name().is_some() {
726+
write_variable(var);
727+
}
726728
}
727729
}
728730
VariableCapture::Only(vars) => {

debugger/src/debugger/return_value.rs

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -599,23 +599,47 @@ pub(super) fn write_return_value(
599599
None
600600
};
601601
event.write_option(rwriter, RETVAL, return_type.name(), value);
602+
} else if matches!(left, ValueType::i128 | ValueType::u128) {
603+
let val = {
604+
#[cfg(target_arch = "x86_64")]
605+
{
606+
let rdx_u64 = read_u64(&rdx())?;
607+
let rcx_u64 = read_u64(&rcx())?;
608+
let res_is_rcx = (rdx_u64 == 0 && rcx_u64 == 1)
609+
|| (rdx_u64 == 0 && rcx_u64 == 0);
610+
if res_is_rcx && (read_u64(&rdx())? & 0xF) != 0 {
611+
let v = {
612+
let v = [reg("rsi"), reg("r8")];
613+
&values_to_bytes::<16, _>(v.into_iter(), 2)?
614+
};
615+
Some(rwriter.prim_v(left.primitive_name(), v))
616+
} else if !res_is_rcx && (read_u64(&rdx())? & 0xF) != 0 {
617+
let v = {
618+
let v = [reg("rdi"), reg("r8")];
619+
&values_to_bytes::<16, _>(v.into_iter(), 2)?
620+
};
621+
Some(rwriter.prim_v(left.primitive_name(), v))
622+
} else {
623+
None
624+
}
625+
}
626+
#[cfg(target_arch = "aarch64")]
627+
{
628+
if opt != 0 {
629+
let v = {
630+
let v = [reg("x2"), reg("x3")];
631+
&values_to_bytes::<16, _>(v.into_iter(), 2)?
632+
};
633+
Some(rwriter.prim_v(left.primitive_name(), v))
634+
} else {
635+
None
636+
}
637+
}
638+
};
639+
event.write_option(rwriter, RETVAL, return_type.name(), val);
602640
} else if opt != 0 {
603641
let val = if left_size == 0 {
604642
rwriter.unit_v()
605-
} else if matches!(left, ValueType::i128 | ValueType::u128) {
606-
let v = {
607-
#[cfg(target_arch = "x86_64")]
608-
{
609-
// we are using rcx too
610-
&values_to_bytes::<16, _>([rdx(), rcx()].into_iter(), 2)?
611-
}
612-
#[cfg(target_arch = "aarch64")]
613-
{
614-
let v = [reg("x2"), reg("x3")];
615-
&values_to_bytes::<16, _>(v.into_iter(), 2)?
616-
}
617-
};
618-
rwriter.prim_v(left.primitive_name(), v)
619643
} else if matches!(left, ValueType::Slice(_)) {
620644
get_slice_from_rax_rdx(rwriter, &left, &left_type)?
621645
} else if left.is_thin_ptr() {
@@ -793,17 +817,27 @@ pub(super) fn write_return_value(
793817
{
794818
// Result<i128, i128>, Result<u128, u128>, Result<i128, ()>, Result<(), u128>
795819
log::trace!("{} rcx, rdx", return_type.name());
796-
let res = read_u64(&rax())?;
797-
let v = {
820+
let (res, v) = {
798821
#[cfg(target_arch = "x86_64")]
799822
{
800-
// we are using rcx too
801-
&values_to_bytes::<16, _>([rdx(), rcx()].into_iter(), 2)?
823+
let rdx_u64 = read_u64(&rdx())?;
824+
let rcx_u64 = read_u64(&rcx())?;
825+
let res_is_rcx = (rdx_u64 == 0 && rcx_u64 == 1)
826+
|| (rdx_u64 == 0 && rcx_u64 == 0);
827+
let has_unit = left_size == 0 || right_size == 0;
828+
let res = if res_is_rcx { rcx_u64 } else { rdx_u64 };
829+
let v = if res_is_rcx {
830+
[reg("rsi"), reg("r8")]
831+
} else {
832+
[reg("rdi"), reg("r8")]
833+
};
834+
(res, &values_to_bytes::<16, _>(v.into_iter(), 2)?)
802835
}
803836
#[cfg(target_arch = "aarch64")]
804837
{
838+
let res = read_u64(&rax())?;
805839
let v = [reg("x2"), reg("x3")];
806-
&values_to_bytes::<16, _>(v.into_iter(), 2)?
840+
(res, &values_to_bytes::<16, _>(v.into_iter(), 2)?)
807841
}
808842
};
809843
let val = if left_size == 0 && res == 0 {

debugger/tests/async-1.rs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
mod util;
2+
use util::*;
3+
4+
use anyhow::Result;
5+
use firedbg_rust_debugger::{Bytes, Debugger, Event, EventStream};
6+
use pretty_assertions::assert_eq;
7+
use sea_streamer::{Buffer, Consumer, Message, Producer};
8+
9+
#[tokio::test]
10+
async fn main() -> Result<()> {
11+
let testcase = "async-1";
12+
let (producer, consumer) = setup(testcase).await?;
13+
14+
let mut debugger_params = debugger_params_testbench(testcase);
15+
16+
println!("{:#?}", debugger_params.breakpoints);
17+
18+
Debugger::run(debugger_params, producer.clone());
19+
20+
producer.end().await?;
21+
22+
for i in 0..100 {
23+
let payload = consumer.next().await?.message().into_bytes();
24+
let event = EventStream::read_from(Bytes::from(payload));
25+
println!("#{i} {:?}", event);
26+
27+
match &event {
28+
Event::Breakpoint { .. } => (),
29+
Event::FunctionCall { function_name, .. } => {}
30+
Event::FunctionReturn { function_name, .. } => {}
31+
}
32+
}
33+
34+
Ok(())
35+
}
36+
37+
// function end }
38+
// 1. without {{closure}}: enter future
39+
// 2. with {{closure}}: exit future
40+
//
41+
// function {
42+
// 1. everytime future is re-entered
43+
44+
// #0 FunctionCall { breakpoint_id: 9, thread_id: 12475492, frame_id: 1, stack_pointer: 6123578480, function_name: "main::main", arguments: [] }
45+
// #1 FunctionCall { breakpoint_id: 5, thread_id: 12475492, frame_id: 2, stack_pointer: 6123573392, function_name: "main::uid", arguments: [] }
46+
// #2 FunctionReturn { breakpoint_id: 29, thread_id: 12475492, frame_id: 2, function_name: "main::uid", return_value: Prim(u64(5581)) }
47+
// #3 FunctionCall { breakpoint_id: 7, thread_id: 12475492, frame_id: 3, stack_pointer: 6123573408, function_name: "main::sleep2", arguments: [("ctx", Prim(u64(5581)))] }
48+
// #4 FunctionReturn { breakpoint_id: 30, thread_id: 12475492, frame_id: 3, function_name: "main::sleep2", return_value: Opaque }
49+
// #5 FunctionCall { breakpoint_id: 8, thread_id: 12475492, frame_id: 4, stack_pointer: 6123573408, function_name: "main::sleep3", arguments: [("ctx", Prim(u64(5581)))] }
50+
// #6 FunctionReturn { breakpoint_id: 31, thread_id: 12475492, frame_id: 4, function_name: "main::sleep3", return_value: Opaque }
51+
// #7 FunctionCall { breakpoint_id: 7, thread_id: 12475492, frame_id: 5, stack_pointer: 6123571040, function_name: "main::sleep2::{{closure}}", arguments: [] }
52+
// #8 FunctionCall { breakpoint_id: 5, thread_id: 12475492, frame_id: 6, stack_pointer: 6123571008, function_name: "main::uid", arguments: [] }
53+
// #9 FunctionReturn { breakpoint_id: 29, thread_id: 12475492, frame_id: 6, function_name: "main::uid", return_value: Prim(u64(6411)) }
54+
// #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)))] }
55+
// #11 FunctionReturn { breakpoint_id: 35, thread_id: 12475492, frame_id: 7, function_name: "main::sleeper", return_value: Opaque }
56+
// #12 FunctionCall { breakpoint_id: 6, thread_id: 12475492, frame_id: 8, stack_pointer: 6123570160, function_name: "main::sleeper::{{closure}}", arguments: [] }
57+
// #13 FunctionCall { breakpoint_id: 5, thread_id: 12475492, frame_id: 9, stack_pointer: 6123570128, function_name: "main::uid", arguments: [] }
58+
// #14 FunctionReturn { breakpoint_id: 29, thread_id: 12475492, frame_id: 9, function_name: "main::uid", return_value: Prim(u64(3181)) }
59+
// #15 FunctionReturn { breakpoint_id: 36, thread_id: 12475492, frame_id: 8, function_name: "main::sleeper::{{closure}}", return_value: Opaque }
60+
// #16 FunctionReturn { breakpoint_id: 32, thread_id: 12475492, frame_id: 5, function_name: "main::sleep2::{{closure}}", return_value: Opaque }
61+
// #17 FunctionCall { breakpoint_id: 8, thread_id: 12475492, frame_id: 10, stack_pointer: 6123571584, function_name: "main::sleep3::{{closure}}", arguments: [] }
62+
// #18 FunctionCall { breakpoint_id: 5, thread_id: 12475492, frame_id: 11, stack_pointer: 6123571552, function_name: "main::uid", arguments: [] }
63+
// #19 FunctionReturn { breakpoint_id: 29, thread_id: 12475492, frame_id: 11, function_name: "main::uid", return_value: Prim(u64(3079)) }
64+
// #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)))] }
65+
// #21 FunctionReturn { breakpoint_id: 35, thread_id: 12475492, frame_id: 12, function_name: "main::sleeper", return_value: Opaque }
66+
// #22 FunctionCall { breakpoint_id: 6, thread_id: 12475492, frame_id: 13, stack_pointer: 6123570704, function_name: "main::sleeper::{{closure}}", arguments: [] }
67+
// #23 FunctionCall { breakpoint_id: 5, thread_id: 12475492, frame_id: 14, stack_pointer: 6123570672, function_name: "main::uid", arguments: [] }
68+
// #24 FunctionReturn { breakpoint_id: 29, thread_id: 12475492, frame_id: 14, function_name: "main::uid", return_value: Prim(u64(9970)) }
69+
// #25 FunctionReturn { breakpoint_id: 36, thread_id: 12475492, frame_id: 13, function_name: "main::sleeper::{{closure}}", return_value: Opaque }
70+
// #26 FunctionReturn { breakpoint_id: 38, thread_id: 12475492, frame_id: 10, function_name: "main::sleep3::{{closure}}", return_value: Opaque }
71+
// #27 FunctionCall { breakpoint_id: 8, thread_id: 12475492, frame_id: 15, stack_pointer: 6123571584, function_name: "main::sleep3::{{closure}}", arguments: [] }
72+
// #28 FunctionCall { breakpoint_id: 6, thread_id: 12475492, frame_id: 16, stack_pointer: 6123570704, function_name: "main::sleeper::{{closure}}", arguments: [] }
73+
// #29 FunctionReturn { breakpoint_id: 37, thread_id: 12475492, frame_id: 16, function_name: "main::sleeper::{{closure}}", return_value: Opaque }
74+
// #30 FunctionReturn { breakpoint_id: 39, thread_id: 12475492, frame_id: 15, function_name: "main::sleep3::{{closure}}", return_value: Opaque }
75+
// #31 FunctionCall { breakpoint_id: 7, thread_id: 12475492, frame_id: 17, stack_pointer: 6123571040, function_name: "main::sleep2::{{closure}}", arguments: [] }
76+
// #32 FunctionCall { breakpoint_id: 6, thread_id: 12475492, frame_id: 18, stack_pointer: 6123570160, function_name: "main::sleeper::{{closure}}", arguments: [] }
77+
// #33 FunctionReturn { breakpoint_id: 37, thread_id: 12475492, frame_id: 18, function_name: "main::sleeper::{{closure}}", return_value: Opaque }
78+
// #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)))] }
79+
// #35 FunctionReturn { breakpoint_id: 35, thread_id: 12475492, frame_id: 19, function_name: "main::sleeper", return_value: Opaque }
80+
// #36 FunctionCall { breakpoint_id: 6, thread_id: 12475492, frame_id: 20, stack_pointer: 6123570160, function_name: "main::sleeper::{{closure}}", arguments: [] }
81+
// #37 FunctionCall { breakpoint_id: 5, thread_id: 12475492, frame_id: 21, stack_pointer: 6123570128, function_name: "main::uid", arguments: [] }
82+
// #38 FunctionReturn { breakpoint_id: 29, thread_id: 12475492, frame_id: 21, function_name: "main::uid", return_value: Prim(u64(1054)) }
83+
// #39 FunctionReturn { breakpoint_id: 36, thread_id: 12475492, frame_id: 20, function_name: "main::sleeper::{{closure}}", return_value: Opaque }
84+
// #40 FunctionReturn { breakpoint_id: 33, thread_id: 12475492, frame_id: 17, function_name: "main::sleep2::{{closure}}", return_value: Opaque }
85+
// #41 FunctionCall { breakpoint_id: 7, thread_id: 12475492, frame_id: 22, stack_pointer: 6123571040, function_name: "main::sleep2::{{closure}}", arguments: [] }
86+
// #42 FunctionCall { breakpoint_id: 6, thread_id: 12475492, frame_id: 23, stack_pointer: 6123570160, function_name: "main::sleeper::{{closure}}", arguments: [] }
87+
// #43 FunctionReturn { breakpoint_id: 37, thread_id: 12475492, frame_id: 23, function_name: "main::sleeper::{{closure}}", return_value: Opaque }
88+
// #44 FunctionReturn { breakpoint_id: 34, thread_id: 12475492, frame_id: 22, function_name: "main::sleep2::{{closure}}", return_value: Opaque }
89+
// #45 FunctionReturn { breakpoint_id: 10, thread_id: 12475492, frame_id: 1, function_name: "main::main", return_value: Unit }

debugger/tests/util.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use std::{
1414
fs::{File, OpenOptions},
1515
io::Write,
1616
path::Path,
17+
time::SystemTime,
1718
};
1819

1920
#[derive(Debug)]
@@ -52,6 +53,31 @@ pub fn debugger_params_from_file(testcase: &str) -> DebuggerParams {
5253
}
5354
}
5455

56+
pub fn debugger_params_testbench(testcase: &str) -> DebuggerParams {
57+
let path = format!("../testbench/{testcase}/src/bin/main.rs");
58+
let mut files = vec![Default::default()];
59+
files.push(SourceFile {
60+
id: 1,
61+
path: path.clone(),
62+
crate_name: testcase.into(),
63+
modified: SystemTime::UNIX_EPOCH,
64+
});
65+
66+
let mut breakpoints = vec![Default::default()];
67+
for func in firedbg_rust_parser::parse_file(&path).unwrap() {
68+
breakpoints.push(new_breakpoint(breakpoints.len() as u32, 1, func));
69+
}
70+
71+
// TODO cargo b --bin main
72+
73+
DebuggerParams {
74+
binary: format!("../testbench/{testcase}/target/debug/main"),
75+
files,
76+
breakpoints,
77+
arguments: vec![],
78+
}
79+
}
80+
5581
pub fn generate_rust_program(testcase: &str, content: &str) -> DebuggerParams {
5682
let path = format!("testcases/generated/{testcase}");
5783
let src = format!("{path}.rs");

indexer/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "firedbg-stream-indexer"
3-
version = "1.76.0"
3+
version = "1.77.0"
44
edition = "2021"
55
license = "MIT OR Apache-2.0"
66
authors = [
@@ -28,7 +28,7 @@ tokio = { version = "1", optional = true }
2828
pretty_assertions = { version = "1", optional = true }
2929
async-trait = { version = "0.1", optional = true }
3030
# workspace
31-
firedbg-rust-debugger = { path = "../debugger", version = "1.76.0", default-features = false }
31+
firedbg-rust-debugger = { path = "../debugger", version = "1.77.0", default-features = false }
3232

3333
[features]
3434
# The base feature only exports the sea-orm entities

indexer/src/validator.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ use crate::{
99
Processor,
1010
};
1111
use firedbg_rust_debugger::{
12-
Breakpoint, Event, EventStream, InfoMessage, SourceFile, BREAKPOINT_STREAM, EVENT_STREAM,
13-
FILE_STREAM, INFO_STREAM,
12+
Breakpoint, Event, EventStream, InfoMessage, SourceFile, ALLOCATION_STREAM, BREAKPOINT_STREAM,
13+
EVENT_STREAM, FILE_STREAM, INFO_STREAM,
1414
};
1515

1616
#[derive(Debug, Default, Serialize, Deserialize)]
@@ -57,6 +57,7 @@ impl Processor for Validator {
5757
event.redacted();
5858
self.data.events.push(event);
5959
}
60+
ALLOCATION_STREAM => {}
6061
_ => anyhow::bail!("Unexpected stream key {}", message.stream_key()),
6162
}
6263
}

parser/src/def/function.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize};
55
pub struct FunctionDef {
66
pub ty: FunctionType,
77
pub loc: BreakableSpan,
8+
pub end: LineColumn,
89
}
910

1011
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]

parser/src/parsing/function.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use crate::{parsing::parse_body_loc, FunctionDef, FunctionType};
1+
use crate::{
2+
parsing::{parse_body_end, parse_body_loc},
3+
FunctionDef, FunctionType,
4+
};
25
use syn::__private::ToTokens;
36

47
// Parse function breakpoints
@@ -35,7 +38,8 @@ impl ParseFunction for syn::ItemFn {
3538
return_type,
3639
};
3740
let loc = parse_body_loc(&self.block);
38-
let parent_breakpoint = FunctionDef { ty, loc };
41+
let end = parse_body_end(&self.block);
42+
let parent_breakpoint = FunctionDef { ty, loc, end };
3943
parse_nested_func(parent_breakpoint, &self.block)
4044
}
4145
}
@@ -84,7 +88,8 @@ impl ParseFunction for (&syn::ItemImpl, &syn::ImplItemFn) {
8488
},
8589
};
8690
let loc = parse_body_loc(&impl_item_fn.block);
87-
let parent_breakpoint = FunctionDef { ty, loc };
91+
let end = parse_body_end(&impl_item_fn.block);
92+
let parent_breakpoint = FunctionDef { ty, loc, end };
8893
parse_nested_func(parent_breakpoint, &impl_item_fn.block)
8994
}
9095
}
@@ -124,7 +129,8 @@ impl ParseFunction for (&syn::ItemTrait, &syn::TraitItemFn) {
124129
return_type,
125130
};
126131
let loc = parse_body_loc(block);
127-
let parent_breakpoint = FunctionDef { ty, loc };
132+
let end = parse_body_end(block);
133+
let parent_breakpoint = FunctionDef { ty, loc, end };
128134
parse_nested_func(parent_breakpoint, block)
129135
}
130136
None => Vec::new(),

parser/src/parsing/source.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ pub(crate) fn parse_body_loc(block: &syn::Block) -> BreakableSpan {
99
}
1010
}
1111

12+
pub(crate) fn parse_body_end(block: &syn::Block) -> LineColumn {
13+
block.span().end().into_loc()
14+
}
15+
1216
/// Parse the line and column number of function block.
1317
///
1418
/// A function block is wrapped in a pair of braces, i.e. `{ ... }`

0 commit comments

Comments
 (0)