@@ -84,42 +84,47 @@ fn expect_aborted(status: ExitStatus) {
8484
8585 #[ cfg( target_os = "android" ) ]
8686 {
87- // Android signals an abort() call with SIGSEGV at address 0xdeadbaad
88- // See e.g. https://groups.google.com/g/android-ndk/c/laW1CJc7Icc
89- assert ! ( signal == libc:: SIGSEGV ) ;
90-
91- // Additional checks performed:
92- // 1. Find last tombstone (similar to coredump but in text format) from the
93- // same executable (path) as we are (must be because of usage of fork):
94- // This ensures that we look into the correct tombstone.
95- // 2. Cause of crash is a SIGSEGV with address 0xdeadbaad.
96- // 3. libc::abort call is in one of top two functions on callstack.
97- // The last two steps distinguish between a normal SIGSEGV and one caused
98- // by libc::abort.
99-
100- let this_exe = std:: env:: current_exe ( ) . unwrap ( ) . into_os_string ( ) . into_string ( ) . unwrap ( ) ;
101- let exe_string = format ! ( ">>> {this_exe} <<<" ) ;
102- let tombstone = ( 0 ..100 )
103- . map ( |n| format ! ( "/data/tombstones/tombstone_{n:02}" ) )
104- . filter ( |f| std:: path:: Path :: new ( & f) . exists ( ) )
105- . map ( |f| std:: fs:: read_to_string ( & f) . expect ( "Cannot read tombstone file" ) )
106- . filter ( |f| f. contains ( & exe_string) )
107- . last ( )
108- . expect ( "no tombstone found" ) ;
109-
110- println ! ( "Content of tombstone:\n {tombstone}" ) ;
111-
112- assert ! (
113- tombstone. contains( "signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadbaad" )
114- ) ;
115- let abort_on_top = tombstone
116- . lines ( )
117- . skip_while ( |l| !l. contains ( "backtrace:" ) )
118- . skip ( 1 )
119- . take_while ( |l| l. starts_with ( " #" ) )
120- . take ( 2 )
121- . any ( |f| f. contains ( "/system/lib/libc.so (abort" ) ) ;
122- assert ! ( abort_on_top) ;
87+ assert ! ( signal == libc:: SIGABRT || signal == libc:: SIGSEGV ) ;
88+
89+ if signal == libc:: SIGSEGV {
90+ // Pre-KitKat versions of Android signal an abort() with SIGSEGV at address 0xdeadbaad
91+ // See e.g. https://groups.google.com/g/android-ndk/c/laW1CJc7Icc
92+ //
93+ // This behavior was changed in KitKat to send a standard SIGABRT signal.
94+ // See: https://r.android.com/60341
95+ //
96+ // Additional checks performed:
97+ // 1. Find last tombstone (similar to coredump but in text format) from the
98+ // same executable (path) as we are (must be because of usage of fork):
99+ // This ensures that we look into the correct tombstone.
100+ // 2. Cause of crash is a SIGSEGV with address 0xdeadbaad.
101+ // 3. libc::abort call is in one of top two functions on callstack.
102+ // The last two steps distinguish between a normal SIGSEGV and one caused
103+ // by libc::abort.
104+
105+ let this_exe = std:: env:: current_exe ( ) . unwrap ( ) . into_os_string ( ) . into_string ( ) . unwrap ( ) ;
106+ let exe_string = format ! ( ">>> {this_exe} <<<" ) ;
107+ let tombstone = ( 0 ..100 )
108+ . map ( |n| format ! ( "/data/tombstones/tombstone_{n:02}" ) )
109+ . filter ( |f| std:: path:: Path :: new ( & f) . exists ( ) )
110+ . map ( |f| std:: fs:: read_to_string ( & f) . expect ( "Cannot read tombstone file" ) )
111+ . filter ( |f| f. contains ( & exe_string) )
112+ . last ( )
113+ . expect ( "no tombstone found" ) ;
114+
115+ println ! ( "Content of tombstone:\n {tombstone}" ) ;
116+
117+ assert ! ( tombstone
118+ . contains( "signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr deadbaad" ) ) ;
119+ let abort_on_top = tombstone
120+ . lines ( )
121+ . skip_while ( |l| !l. contains ( "backtrace:" ) )
122+ . skip ( 1 )
123+ . take_while ( |l| l. starts_with ( " #" ) )
124+ . take ( 2 )
125+ . any ( |f| f. contains ( "/system/lib/libc.so (abort" ) ) ;
126+ assert ! ( abort_on_top) ;
127+ }
123128 }
124129}
125130
0 commit comments