| 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)); |
| } |