@@ -198,6 +198,87 @@ fn test_crash_tracking_errors_intake_uds_socket() {
198198 ) ;
199199}
200200
201+ #[ test]
202+ #[ cfg_attr( miri, ignore) ]
203+ fn test_crash_tracking_bin_panic ( ) {
204+ test_crash_tracking_app ( "panic" ) ;
205+ }
206+
207+ #[ test]
208+ #[ cfg_attr( miri, ignore) ]
209+ fn test_crash_tracking_bin_panic ( ) {
210+ test_crash_tracking_app ( "segfault" ) ;
211+ }
212+
213+ fn test_crash_tracking_app ( crash_type : & str ) {
214+ let ( _, crashtracker_receiver) = setup_crashtracking_crates ( BuildProfile :: Release ) ;
215+
216+ let crashing_app = ArtifactsBuild {
217+ name : "crashing_test_app" . to_owned ( ) ,
218+ build_profile : BuildProfile :: Debug ,
219+ artifact_type : ArtifactType :: Bin ,
220+ triple_target : None ,
221+ ..Default :: default ( )
222+ } ;
223+
224+ let fixtures = setup_test_fixtures ( & [ & crashtracker_receiver, & crashing_app] ) ;
225+
226+ let mut p = process:: Command :: new ( & fixtures. artifacts [ & crashing_app] )
227+ . arg ( format ! ( "file://{}" , fixtures. crash_profile_path. display( ) ) )
228+ . arg ( fixtures. artifacts [ & crashtracker_receiver] . as_os_str ( ) )
229+ . arg ( & fixtures. output_dir )
230+ . arg ( crash_type)
231+ . spawn ( )
232+ . unwrap ( ) ;
233+
234+ let exit_status = bin_tests:: timeit!( "exit after signal" , {
235+ eprintln!( "Waiting for exit" ) ;
236+ p. wait( ) . unwrap( )
237+ } ) ;
238+ assert ! ( !exit_status. success( ) ) ;
239+
240+ let stderr_path = format ! ( "{0}/out.stderr" , fixtures. output_dir. display( ) ) ;
241+ let stderr = fs:: read ( stderr_path)
242+ . context ( "reading crashtracker stderr" )
243+ . unwrap ( ) ;
244+ let stdout_path = format ! ( "{0}/out.stdout" , fixtures. output_dir. display( ) ) ;
245+ let stdout = fs:: read ( stdout_path)
246+ . context ( "reading crashtracker stdout" )
247+ . unwrap ( ) ;
248+ let s = String :: from_utf8 ( stderr) ;
249+ assert ! (
250+ matches!(
251+ s. as_deref( ) ,
252+ Ok ( "" ) | Ok ( "Failed to fully receive crash. Exit state was: StackTrace([])\n " )
253+ | Ok ( "Failed to fully receive crash. Exit state was: InternalError(\" {\\ \" ip\\ \" : \\ \" \" )\n " ) ,
254+ ) ,
255+ "got {s:?}"
256+ ) ;
257+ assert_eq ! ( Ok ( "" ) , String :: from_utf8( stdout) . as_deref( ) ) ;
258+
259+ let crash_profile = fs:: read ( fixtures. crash_profile_path )
260+ . context ( "reading crashtracker profiling payload" )
261+ . unwrap ( ) ;
262+ let crash_payload = serde_json:: from_slice :: < serde_json:: Value > ( & crash_profile)
263+ . context ( "deserializing crashtracker profiling payload to json" )
264+ . unwrap ( ) ;
265+
266+ let sig_info = & crash_payload[ "sig_info" ] ;
267+
268+ match crash_type {
269+ "panic" => {
270+ let error = & crash_payload[ "error" ] ;
271+ let expected_message = "program panicked" ;
272+ assert_eq ! ( error[ "message" ] . as_str( ) . unwrap( ) , expected_message) ;
273+ }
274+ "segfault" => {
275+ let error = & crash_payload[ "error" ] ;
276+ assert_error_message ( & error[ "message" ] , sig_info) ;
277+ }
278+ _ => unreachable ! ( "Invalid crash type: {crash_type}" ) ,
279+ }
280+ }
281+
201282// This test is disabled for now on x86_64 musl and macos
202283// It seems that on aarch64 musl, libc has CFI which allows
203284// unwinding passed the signal frame.
@@ -208,9 +289,6 @@ fn test_crasht_tracking_validate_callstack() {
208289 test_crash_tracking_callstack ( )
209290}
210291
211- #[ test]
212- #[ cfg( not( any( all( target_arch = "x86_64" , target_env = "musl" ) , target_os = "macos" ) ) ) ]
213- #[ cfg_attr( miri, ignore) ]
214292fn test_crash_tracking_callstack ( ) {
215293 let ( _, crashtracker_receiver) = setup_crashtracking_crates ( BuildProfile :: Release ) ;
216294
@@ -230,6 +308,7 @@ fn test_crash_tracking_callstack() {
230308 . arg ( format ! ( "file://{}" , fixtures. crash_profile_path. display( ) ) )
231309 . arg ( fixtures. artifacts [ & crashtracker_receiver] . as_os_str ( ) )
232310 . arg ( & fixtures. output_dir )
311+ . arg ( "segfault" )
233312 . spawn ( )
234313 . unwrap ( ) ;
235314
0 commit comments