-
Notifications
You must be signed in to change notification settings - Fork 13k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #135192 - jdupak-ms:cdb-tests, r=wesleywiser
Add and improve debuginfo tests for Windows Adds new test for closures and function pointers. Improves robustness of existing tests by sorting wildcard matched outputs. try-job: i686-msvc
- Loading branch information
Showing
6 changed files
with
294 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
//@ only-cdb | ||
//@ compile-flags:-g | ||
|
||
// === CDB TESTS =================================================================================== | ||
// Generic functions cause ambigious breakpoints. | ||
// cdb-command:dx @$debuggerRootNamespace.Debugger.Settings.EngineInitialization.ResolveAmbiguousBreakpoints = true; | ||
// cdb-command:bp `closures.rs:57` | ||
// cdb-command:g | ||
// cdb-command:dx add_closure | ||
// cdb-check:add_closure [Type: closures::main::closure_env$0] | ||
// cdb-check: [+0x[...]] _ref__base_value : 0x[...] : 42 [Type: int *] | ||
// cdb-command:dx increment | ||
// cdb-check:increment [Type: closures::main::closure_env$1] | ||
// cdb-check: [+0x[...]] _ref__count : 0x[...] : 2 [Type: int *] | ||
// cdb-command:dx consume_closure | ||
// cdb-check:consume_closure [Type: closures::main::closure_env$2] | ||
// cdb-check: [+0x[...]] x : [...] [Type: alloc::string::String] | ||
// cdb-check: [+0x[...]] _ref__base_value : 0x[...] : 42 [Type: int *] | ||
// cdb-command:dx simple_closure | ||
// cdb-checksimple_closure [Type: closures::main::closure_env$5] | ||
// cdb-check: [+0x[...]] _ref__base_value : 0x[...] : 42 [Type: int *] | ||
// cdb-command:g | ||
// cdb-command:dx first_closure | ||
// cdb-check:first_closure [Type: closures::main::closure_env$6] | ||
// cdb-check: [+0x[...]] _ref__variable : 0x[...] : 1 [Type: int *] | ||
// cdb-check: [+0x[...]] _ref__constant : 0x[...] : 2 [Type: int *] | ||
// cdb-check: [+0x[...]] _ref__a_struct : 0x[...] [Type: closures::Struct *] | ||
// cdb-check: [+0x[...]] _ref__struct_ref : 0x[...] [Type: closures::Struct * *] | ||
// cdb-check: [+0x[...]] _ref__owned_value : 0x[...] [Type: int * *] | ||
// cdb-command:g | ||
// cdb-command:dx many_param_closure | ||
// cdb-check:many_param_closure [Type: closures::main::closure_env$7] | ||
// cdb-check: [+0x[...]] _ref__base_value : 0x[...] : 42 [Type: int *] | ||
// cdb-command:g | ||
// cdb-command:dv | ||
// cdb-command:dx generic_closure | ||
// cdb-check:generic_closure [Type: closures::generic_func::closure_env$0<i32>] | ||
// cdb-check: [+0x[...]] _ref__x : 0x[...] : 42 [Type: int *] | ||
// cdb-command:g | ||
// cdb-command:dx generic_closure | ||
// cdb-check:generic_closure [Type: closures::generic_func::closure_env$0<ref$<str$> >] | ||
// cdb-check: [+0x000] _ref__x : 0x[...] : "base_value" [Type: ref$<str$> *] | ||
// cdb-command:g | ||
// cdb-command:dx second_closure | ||
// cdb-check:second_closure [Type: closures::main::closure_env$8] | ||
// cdb-check: [+0x[...]] _ref__variable : 0x[...] : 2 [Type: int *] | ||
// cdb-check: [+0x[...]] _ref__constant : 0x[...] : 2 [Type: int *] | ||
// cdb-check: [+0x[...]] _ref__a_struct : 0x[...] [Type: closures::Struct *] | ||
// cdb-check: [+0x[...]] _ref__struct_ref : 0x[...] [Type: closures::Struct * *] | ||
// cdb-check: [+0x[...]] _ref__owned_value : 0x[...] [Type: int * *] | ||
|
||
#[inline(never)] | ||
fn generic_func<Tfunc: std::fmt::Debug>(x: Tfunc) { | ||
let generic_closure = |a: i32| { | ||
println!("{:?} {}", x, a); | ||
}; | ||
|
||
_zzz(); // #break | ||
|
||
// rustc really wants to inline this closure, so we use black_box instead of calling it | ||
std::hint::black_box(generic_closure); | ||
} | ||
|
||
struct Struct { | ||
a: isize, | ||
b: f64, | ||
c: usize, | ||
} | ||
|
||
fn main() { | ||
let base_value: i32 = 42; | ||
let mut count: i32 = 0; | ||
|
||
let add_closure = |a: i32, b: i32| a + b + base_value; | ||
|
||
add_closure(40, 2); | ||
|
||
let mut increment = || { | ||
count += 1; | ||
}; | ||
|
||
increment(); // count: 1 | ||
increment(); // count: 2 | ||
|
||
let x = String::from("hello"); | ||
|
||
// Define a closure that consumes the captured variable `x` | ||
let consume_closure = move || { | ||
drop(x); | ||
base_value + 1 | ||
}; | ||
|
||
consume_closure(); | ||
|
||
let paramless_closure = || 42_i32; | ||
|
||
let void_closure = |a: i32| { | ||
println!("Closure with arg: {:?}", a); | ||
}; | ||
|
||
let simple_closure = || { | ||
let incremented_value = base_value + 1; | ||
incremented_value | ||
}; | ||
|
||
let result = /*42; */ add_closure(40, 2); | ||
println!("Result: {:?}", result); | ||
void_closure(result); | ||
let result = simple_closure(); | ||
println!("Result: {:?}", result); | ||
|
||
let mut variable: i32 = 1; | ||
let constant: i32 = 2; | ||
|
||
let a_struct = Struct { a: -3, b: 4.5, c: 5 }; | ||
|
||
_zzz(); // #break | ||
|
||
let struct_ref = &a_struct; | ||
let owned_value: Box<i32> = Box::new(6); | ||
|
||
{ | ||
let mut first_closure = || { | ||
variable = constant + a_struct.a as i32 + struct_ref.a as i32 + *owned_value; | ||
}; | ||
|
||
_zzz(); // #break | ||
|
||
first_closure(); | ||
} | ||
|
||
let many_param_closure = | ||
|a: i32, b: f64, c: usize, d: Struct| base_value + a + b as i32 + c as i32 + d.c as i32; | ||
|
||
_zzz(); // #break | ||
|
||
many_param_closure(1, 2.0, 3, Struct { a: 4, b: 5.0, c: 6 }); | ||
|
||
generic_func(42); | ||
generic_func("base_value"); | ||
|
||
{ | ||
let mut second_closure = || { | ||
variable = constant + a_struct.a as i32 + struct_ref.a as i32 + *owned_value; | ||
}; | ||
|
||
_zzz(); // #break | ||
|
||
second_closure(); | ||
} | ||
} | ||
|
||
fn _zzz() { | ||
() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#![feature(async_closure)] | ||
//@ only-cdb | ||
//@ compile-flags:-g --edition=2021 | ||
|
||
// === CDB TESTS ================================================================================== | ||
|
||
// cdb-command: g | ||
// cdb-command: dx closure | ||
// cdb-check:closure [Type: coroutine_closure::main::closure_env$0] | ||
// cdb-check: [+0x[...]] y : "" [Type: alloc::string::String] | ||
// cdb-check: [+0x[...]] x : "" [Type: alloc::string::String] | ||
#![allow(unused)] | ||
fn main() { | ||
let x = String::new(); | ||
let y = String::new(); | ||
let closure = async move || { | ||
drop(y); | ||
println!("{x}"); | ||
}; | ||
|
||
_zzz(); // #break | ||
|
||
std::hint::black_box(closure); | ||
} | ||
|
||
#[inline(never)] | ||
fn _zzz() { | ||
() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
//@ only-cdb | ||
//@ compile-flags:-g | ||
|
||
// === CDB TESTS ================================================================================== | ||
|
||
// cdb-command: g | ||
// cdb-command: dx basic | ||
// cdb-check: basic : [...] : a!core::ops::function::FnOnce::call_once<fn_ptr::main::closure_env$0,tuple$<i32,i32> >+0x0 [Type: int (__cdecl*)(int,int)] | ||
// cdb-check: a!core::ops::function::FnOnce::call_once<fn_ptr::main::closure_env$0,tuple$<i32,i32> >+0x0 [Type: int __cdecl(int,int)] | ||
|
||
// cdb-command: dx paramless | ||
// cdb-check: paramless : [...] : a!core::ops::function::FnOnce::call_once<fn_ptr::main::closure_env$1,tuple$<> >+0x0 [Type: int (__cdecl*)()] | ||
// cdb-check: a!core::ops::function::FnOnce::call_once<fn_ptr::main::closure_env$1,tuple$<> >+0x0 [Type: int __cdecl()] | ||
|
||
// cdb-command: dx my_struct | ||
// cdb-check: my_struct [Type: fn_ptr::MyStruct] | ||
// cdb-check: [+0x000] my_field : [...] : a!core::ops::function::FnOnce::call_once<fn_ptr::main::closure_env$2,tuple$<ref$<fn_ptr::MyStruct> > >+0x0 [Type: int (__cdecl*)(fn_ptr::MyStruct *)] | ||
|
||
// cdb-command: dx non_rec_struct | ||
// cdb-check: non_rec_struct [Type: fn_ptr::NonRecStruct] | ||
// cdb-check: [+0x000] my_field : [...] : a!core::ops::function::FnOnce::call_once<fn_ptr::main::closure_env$3,tuple$<i32> >+0x0 [Type: int (__cdecl*)(int)] | ||
|
||
type BasicFnPtr = fn(i32, i32) -> i32; | ||
|
||
pub type ParamlessFnPtr = fn() -> i32; | ||
|
||
type MyFnPtr = fn(b: &MyStruct) -> i32; | ||
|
||
type NonRecFnPtr = fn(i: i32) -> i32; | ||
|
||
struct MyStruct { | ||
my_field: MyFnPtr, | ||
} | ||
|
||
struct NonRecStruct { | ||
my_field: NonRecFnPtr, | ||
} | ||
|
||
fn main() { | ||
let basic: BasicFnPtr = |a, b| a + b; | ||
let paramless: ParamlessFnPtr = || 1; | ||
let my_struct = MyStruct { my_field: |_| 1 }; | ||
let non_rec_struct = NonRecStruct { my_field: |i| i }; | ||
|
||
_zzz(); // #break | ||
} | ||
|
||
#[inline(never)] | ||
fn _zzz() { | ||
() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.