summaryrefslogtreecommitdiffstats
path: root/library/backtrace/crates/cpp_smoke_test/tests/smoke.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/backtrace/crates/cpp_smoke_test/tests/smoke.rs')
-rw-r--r--library/backtrace/crates/cpp_smoke_test/tests/smoke.rs73
1 files changed, 73 insertions, 0 deletions
diff --git a/library/backtrace/crates/cpp_smoke_test/tests/smoke.rs b/library/backtrace/crates/cpp_smoke_test/tests/smoke.rs
new file mode 100644
index 000000000..b9aef47f5
--- /dev/null
+++ b/library/backtrace/crates/cpp_smoke_test/tests/smoke.rs
@@ -0,0 +1,73 @@
+extern crate backtrace;
+extern crate cpp_smoke_test;
+
+use std::sync::atomic::{AtomicBool, Ordering};
+
+extern "C" {
+ fn cpp_trampoline(func: extern "C" fn()) -> ();
+}
+
+#[test]
+#[ignore] // fixme(fitzgen/cpp_demangle#73)
+fn smoke_test_cpp() {
+ static RAN_ASSERTS: AtomicBool = AtomicBool::new(false);
+
+ extern "C" fn assert_cpp_frames() {
+ let mut physical_frames = Vec::new();
+ backtrace::trace(|cx| {
+ physical_frames.push(cx.ip());
+
+ // We only want to capture this closure's frame, assert_cpp_frames,
+ // space::templated_trampoline, and cpp_trampoline. Those are
+ // logical frames, which might be inlined into fewer physical
+ // frames, so we may end up with extra logical frames after
+ // resolving these.
+ physical_frames.len() < 4
+ });
+
+ let names: Vec<_> = physical_frames
+ .into_iter()
+ .flat_map(|ip| {
+ let mut logical_frame_names = vec![];
+
+ backtrace::resolve(ip, |sym| {
+ let sym_name = sym.name().expect("Should have a symbol name");
+ let demangled = sym_name.to_string();
+ logical_frame_names.push(demangled);
+ });
+
+ assert!(
+ !logical_frame_names.is_empty(),
+ "Should have resolved at least one symbol for the physical frame"
+ );
+
+ logical_frame_names
+ })
+ // Skip the backtrace::trace closure and assert_cpp_frames, and then
+ // take the two C++ frame names.
+ .skip_while(|name| !name.contains("trampoline"))
+ .take(2)
+ .collect();
+
+ println!("actual names = {:#?}", names);
+
+ let expected = [
+ "void space::templated_trampoline<void (*)()>(void (*)())",
+ "cpp_trampoline",
+ ];
+ println!("expected names = {:#?}", expected);
+
+ assert_eq!(names.len(), expected.len());
+ for (actual, expected) in names.iter().zip(expected.iter()) {
+ assert_eq!(actual, expected);
+ }
+
+ RAN_ASSERTS.store(true, Ordering::SeqCst);
+ }
+
+ assert!(!RAN_ASSERTS.load(Ordering::SeqCst));
+ unsafe {
+ cpp_trampoline(assert_cpp_frames);
+ }
+ assert!(RAN_ASSERTS.load(Ordering::SeqCst));
+}