Skip to content

Commit fb401f2

Browse files
committed
1.78.0-beta.1
1 parent d6ed281 commit fb401f2

23 files changed

+276
-91
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## 1.78.0 - Pending
4+
5+
### Versions
6+
7+
+ `1.78.0-beta.1`: 2024-04-23
8+
39
## 1.77.1 - 2024-04-19
410

511
### Bug Fixes

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.77.1"
3+
version = "1.78.0-beta.1"
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.77.1"
3+
version = "1.78.0-beta.1"
44
edition = "2021"
55
license = "MIT OR Apache-2.0"
66
build = "build.rs"

debugger/src/debugger.rs

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,9 @@ fn run(mut params: DebuggerParams, mut producer: SeaProducer) -> Result<()> {
362362
let mut return_immediately = false;
363363
if matches!(
364364
bp_event_type,
365-
BreakpointType::Breakpoint | BreakpointType::FunctionCall { .. }
365+
BreakpointType::Breakpoint
366+
| BreakpointType::FunctionCall { .. }
367+
| BreakpointType::FutureEndpoint
366368
) {
367369
let mut event = if matches!(bp_event_type, BreakpointType::Breakpoint) {
368370
let (active_frame_id, reason) = active_frames
@@ -519,6 +521,25 @@ fn run(mut params: DebuggerParams, mut producer: SeaProducer) -> Result<()> {
519521
}
520522

521523
EventStream::function_call(bp_id, thread_id, active_frames.last().expect("Pushed"))
524+
} else if matches!(bp_event_type, BreakpointType::FutureEndpoint) {
525+
let sb_function = sb_frame.function();
526+
let fn_name = sb_function.name();
527+
let (active_frame_id, reason) = active_frames
528+
.last()
529+
.map(|active_frame| {
530+
(
531+
active_frame.frame_id,
532+
if fn_name.ends_with("::{{closure}}") {
533+
Reason::FutureExit
534+
} else {
535+
Reason::FutureEnter
536+
},
537+
)
538+
})
539+
.unwrap_or_default();
540+
let mut event = EventStream::breakpoint(bp_id, thread_id, active_frame_id, reason);
541+
event.write_string(rwriter, "fn", &fn_name.replace("::{{closure}}", ""));
542+
event
522543
} else {
523544
unreachable!();
524545
};
@@ -1104,6 +1125,14 @@ impl Bytes {
11041125
};
11051126
self.write_value(rwriter, name, bytes.as_bytes());
11061127
}
1128+
1129+
fn write_string(&mut self, rwriter: &mut RValueWriter, name: &str, value: &str) {
1130+
self.identifier(name);
1131+
self.push_str("name");
1132+
self.space();
1133+
self.push_bytes(rwriter.strlit_v(value.as_bytes()));
1134+
self.space();
1135+
}
11071136
}
11081137

11091138
impl Default for Thread {
@@ -1117,7 +1146,7 @@ impl Default for Thread {
11171146
}
11181147

11191148
#[doc(hidden)]
1120-
pub fn new_breakpoint(id: u32, file_id: u32, func: FunctionDef) -> Breakpoint {
1149+
pub fn new_breakpoint(id: u32, file_id: u32, func: &FunctionDef) -> Breakpoint {
11211150
Breakpoint {
11221151
id,
11231152
file_id,
@@ -1130,6 +1159,18 @@ pub fn new_breakpoint(id: u32, file_id: u32, func: FunctionDef) -> Breakpoint {
11301159
}
11311160
}
11321161

1162+
#[doc(hidden)]
1163+
pub fn new_async_breakpoint(id: u32, file_id: u32, func: &FunctionDef) -> Breakpoint {
1164+
Breakpoint {
1165+
id,
1166+
file_id,
1167+
loc: func.end,
1168+
loc_end: None,
1169+
breakpoint_type: BreakpointType::FutureEndpoint,
1170+
capture: VariableCapture::None,
1171+
}
1172+
}
1173+
11331174
fn register_breakpoint(breakpoint_addresses: &mut FxHashMap<u64, BpId>, sb_bp: &SBBreakpoint) {
11341175
for sb_bp_loc in sb_bp.locations() {
11351176
breakpoint_addresses.insert(sb_bp_loc.address().file_address() as u64, BpId(sb_bp.id()));

debugger/src/debugger/config.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ lazy_static::lazy_static! {
3434
pub static ref KEEP_HASH_ORDER: bool = config_bool("KEEP_HASH_ORDER");
3535
/// If set, don't trace heap allocations.
3636
pub static ref DONT_TRACE_ALLOCATION: bool = config_bool("DONT_TRACE_ALLOCATION");
37+
static ref SAMPLE: Option<String> = config_string("SAMPLE");
3738
}
3839

3940
#[doc(hidden)]
@@ -43,20 +44,27 @@ pub fn load_config() -> usize {
4344
}
4445

4546
fn config_usize(key: &str) -> Option<usize> {
46-
match CONFIG.get(key).cloned() {
47-
Some(ConfigValue::u64(v)) => Some(v as usize),
47+
match CONFIG.get(key) {
48+
Some(ConfigValue::u64(v)) => Some(*v as usize),
4849
_ => None,
4950
}
5051
}
5152

5253
/// Unset is false
5354
fn config_bool(key: &str) -> bool {
54-
match CONFIG.get(key).cloned() {
55-
Some(ConfigValue::bool(v)) => v,
55+
match CONFIG.get(key) {
56+
Some(ConfigValue::bool(v)) => *v,
5657
_ => false,
5758
}
5859
}
5960

61+
fn config_string(key: &str) -> Option<String> {
62+
match CONFIG.get(key).cloned() {
63+
Some(ConfigValue::String(v)) => Some(v),
64+
_ => None,
65+
}
66+
}
67+
6068
#[derive(Debug, Clone)]
6169
#[allow(non_camel_case_types)]
6270
enum ConfigValue {

debugger/src/debugger/return_value.rs

Lines changed: 68 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ pub(super) fn write_return_value(
607607
let rcx_u64 = read_u64(&rcx())?;
608608
let res_is_rcx = (rdx_u64 == 0 && rcx_u64 == 1)
609609
|| (rdx_u64 == 0 && rcx_u64 == 0);
610-
if res_is_rcx && (read_u64(&rdx())? & 0xF) != 0 {
610+
if res_is_rcx && (read_u64(&rcx())? & 0xF) != 0 {
611611
let v = {
612612
let v = [reg("rsi"), reg("r8")];
613613
&values_to_bytes::<16, _>(v.into_iter(), 2)?
@@ -824,7 +824,6 @@ pub(super) fn write_return_value(
824824
let rcx_u64 = read_u64(&rcx())?;
825825
let res_is_rcx = (rdx_u64 == 0 && rcx_u64 == 1)
826826
|| (rdx_u64 == 0 && rcx_u64 == 0);
827-
let has_unit = left_size == 0 || right_size == 0;
828827
let res = if res_is_rcx { rcx_u64 } else { rdx_u64 };
829828
let v = if res_is_rcx {
830829
[reg("rsi"), reg("r8")]
@@ -898,6 +897,38 @@ pub(super) fn write_return_value(
898897
val,
899898
);
900899
return Ok(());
900+
} else if cfg!(target_arch = "aarch64")
901+
&& (left_size <= 8 && right_size <= 8)
902+
&& (left.is_integer() && right.is_integer())
903+
&& left.is_signed_integer() != right.is_signed_integer()
904+
{
905+
// since llvm 18; Result<u32, i32> Result<u64, i64>
906+
log::trace!("{} x0, x1", return_type.name());
907+
let res = read_u64(&reg("x0"))?;
908+
let left_or_right = if res == 0 { &left } else { &right };
909+
let val = get_prim_from_rdx(rwriter, left_or_right)?;
910+
event.write_result(rwriter, RETVAL, return_type.name(), res == 0, val);
911+
return Ok(());
912+
} else if cfg!(target_arch = "aarch64")
913+
&& matches!(
914+
(&left, &right),
915+
(ValueType::u128, ValueType::i128) | (ValueType::i128, ValueType::u128)
916+
)
917+
{
918+
// since llvm 18; Result<u128, i128>
919+
log::trace!("{} x0, x2, x3", return_type.name());
920+
let res = read_u64(&reg("x0"))?;
921+
let left_or_right = if res == 0 { &left } else { &right };
922+
let val = rwriter.prim_v(
923+
match left_or_right {
924+
ValueType::u128 => "u128",
925+
ValueType::i128 => "i128",
926+
_ => unreachable!(),
927+
},
928+
&values_to_bytes::<16, _>([reg("x2"), reg("x3")].into_iter(), 2)?,
929+
);
930+
event.write_result(rwriter, RETVAL, return_type.name(), res == 0, val);
931+
return Ok(());
901932
} else if (left_size <= 8 && right_size <= 8) // must fit in register
902933
&& (left == right // same type, easy case
903934
|| (left.is_thin_ptr() && right.is_thin_ptr()) // both are pointers
@@ -919,18 +950,22 @@ pub(super) fn write_return_value(
919950
// this is the complex case, where the discriminant and value are both squashed into the same register
920951
let data = read_u64(&rax())?;
921952
let res = data & 0x1; // select the least significant bit
922-
let b = data.to_ne_bytes();
923-
// print!("bytes = "); for b in b.iter() { print!("{b:02X}"); } log::trace!();
924953
let left_or_right = if res == 0 { &left } else { &right };
925954
let left_or_right_size = if res == 0 { left_size } else { right_size };
926955
let ty = left_or_right.primitive_name();
927956

928-
let val = match left_or_right_size {
929-
// the value is in the 2nd lower word
930-
1 => rwriter.prim_v(ty, &b[1..2]),
931-
2 => rwriter.prim_v(ty, &b[2..4]),
932-
4 => rwriter.prim_v(ty, &b[4..8]),
933-
_ => unreachable!(),
957+
let val = if data == 0 || data == 1 {
958+
let b = read_u64(&rdx())?.to_ne_bytes();
959+
rwriter.prim_v(ty, &b[..left_or_right_size])
960+
} else {
961+
let b = data.to_ne_bytes();
962+
match left_or_right_size {
963+
// the value is in the 2nd lower word
964+
1 => rwriter.prim_v(ty, &b[1..2]),
965+
2 => rwriter.prim_v(ty, &b[2..4]),
966+
4 => rwriter.prim_v(ty, &b[4..8]),
967+
_ => unreachable!(),
968+
}
934969
};
935970
event.write_result(rwriter, RETVAL, return_type.name(), res == 0, val);
936971
} else if (left == ValueType::Unit || right == ValueType::Unit)
@@ -993,9 +1028,29 @@ pub(super) fn write_return_value(
9931028
// Result<i32, i64>, Result<u64, i64>
9941029
#[cfg(target_arch = "x86_64")]
9951030
{
996-
log::trace!("{} pass by stack (rax)", return_type.name());
997-
let sb_value = sb_value_from_rax(return_type)?;
998-
event.write_sb_value(rwriter, &sb_value);
1031+
let data = read_u64(&rax())?;
1032+
if data == 0 || data == 1 {
1033+
let res = data & 0x1; // select the least significant bit
1034+
let left_or_right = if res == 0 { &left } else { &right };
1035+
let left_or_right_size = match (left.size_of(), right.size_of()) {
1036+
(SizeOfType::Sized(left_size), SizeOfType::Sized(right_size)) => {
1037+
if res == 0 {
1038+
left_size
1039+
} else {
1040+
right_size
1041+
}
1042+
}
1043+
_ => unreachable!(),
1044+
};
1045+
let ty = left_or_right.primitive_name();
1046+
let b = read_u64(&rdx())?.to_ne_bytes();
1047+
let val = rwriter.prim_v(ty, &b[..left_or_right_size]);
1048+
event.write_result(rwriter, RETVAL, return_type.name(), res == 0, val);
1049+
} else {
1050+
log::trace!("{} pass by stack (rax)", return_type.name());
1051+
let sb_value = sb_value_from_rax(return_type)?;
1052+
event.write_sb_value(rwriter, &sb_value);
1053+
}
9991054
}
10001055
#[cfg(target_arch = "aarch64")]
10011056
{

debugger/src/event.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,22 @@ impl EventStream {
2323
assert!(source.len() > 0);
2424
let event = match source.get(0) {
2525
b'B' => {
26-
let reason = match source.get(1) {
26+
let mut i = 1;
27+
let reason = match source.get(i) {
2728
b'B' => crate::Reason::Breakpoint,
2829
b'P' => crate::Reason::Panic,
30+
b'F' => {
31+
i += 1;
32+
match source.get(i) {
33+
b'{' => crate::Reason::FutureEnter,
34+
b'}' => crate::Reason::FutureExit,
35+
other => panic!("Unknown reason, got {other:?}"),
36+
}
37+
}
2938
other => panic!("Unknown reason, got {other:?}"),
3039
};
31-
reader.set_source(source, 2);
40+
i += 1;
41+
reader.set_source(source, i);
3242
let breakpoint_id = reader.read_int().unwrap() as u32;
3343
let thread_id = reader.read_int().unwrap();
3444
let frame_id = reader.read_int().unwrap();
@@ -94,7 +104,14 @@ impl EventStream {
94104
bytes.push_byte(match reason {
95105
crate::Reason::Breakpoint => b'B',
96106
crate::Reason::Panic => b'P',
107+
crate::Reason::FutureEnter => b'F',
108+
crate::Reason::FutureExit => b'F',
97109
});
110+
match reason {
111+
crate::Reason::FutureEnter => bytes.push_byte(b'{'),
112+
crate::Reason::FutureExit => bytes.push_byte(b'}'),
113+
_ => (),
114+
}
98115
bytes.integer(bp_id.0);
99116
bytes.integer(thread_id);
100117
bytes.integer(frame_id);

debugger/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ async fn main() -> Result<()> {
144144
modified,
145145
});
146146
for func in functions {
147-
breakpoints.push(new_breakpoint(breakpoints.len() as u32, id, func));
147+
breakpoints.push(new_breakpoint(breakpoints.len() as u32, id, &func));
148148
}
149149
id += 1;
150150
};

0 commit comments

Comments
 (0)