@@ -160,6 +160,44 @@ fn test_crash_tracking_bin_unhandled_exception() {
160160 run_crash_test_with_artifacts ( & config, & artifacts_map, & artifacts, validator) . unwrap ( ) ;
161161}
162162
163+ /// Tests that when a C `assert()` fails, the crash report contains the assertion
164+ /// expression string in the error message.
165+ #[ test]
166+ #[ cfg( target_os = "linux" ) ]
167+ #[ cfg_attr( miri, ignore) ]
168+ fn test_crash_tracking_bin_assert_fail ( ) {
169+ let config = CrashTestConfig :: new (
170+ BuildProfile :: Release ,
171+ TestMode :: DoNothing ,
172+ CrashType :: AssertFail ,
173+ ) ;
174+ let artifacts = StandardArtifacts :: new ( config. profile ) ;
175+ let artifacts_map = fetch_built_artifacts ( & artifacts. as_slice ( ) ) . unwrap ( ) ;
176+
177+ let validator: ValidatorFn = Box :: new ( |payload, fixtures| {
178+ PayloadValidator :: new ( payload)
179+ . validate_error_kind ( "UnixSignal" ) ?
180+ // The assertion expression from the real C assert() macro
181+ . validate_error_message_contains ( "test_value > 0" ) ?
182+ // The function name comes from the C compiler's __func__
183+ . validate_error_message_contains ( "trigger_c_assert" ) ?;
184+
185+ // Validate SIGABRT signal info
186+ let sig_info = & payload[ "sig_info" ] ;
187+ let signo_hr = sig_info[ "si_signo_human_readable" ] . as_str ( ) . unwrap_or ( "" ) ;
188+ anyhow:: ensure!(
189+ signo_hr. contains( "SIGABRT" ) ,
190+ "Expected SIGABRT in signal info, got: {signo_hr}"
191+ ) ;
192+
193+ validate_telemetry ( & fixtures. crash_telemetry_path , "assert_fail" ) ?;
194+
195+ Ok ( ( ) )
196+ } ) ;
197+
198+ run_crash_test_with_artifacts ( & config, & artifacts_map, & artifacts, validator) . unwrap ( ) ;
199+ }
200+
163201/// Tests that when `collect_all_threads` is enabled and the crash is reported via
164202/// `report_unhandled_exception`, the crash report contains entries in `error.threads`
165203/// for background threads with valid stack traces.
@@ -1772,6 +1810,10 @@ fn assert_siginfo_message(sig_info: &Value, crash_typ: &str) {
17721810 || sig_info. is_object( ) && sig_info. as_object( ) . is_none_or( |m| m. is_empty( ) )
17731811 ) ;
17741812 }
1813+ "assert_fail" => {
1814+ assert_eq ! ( sig_info[ "si_signo" ] , libc:: SIGABRT ) ;
1815+ assert_eq ! ( sig_info[ "si_signo_human_readable" ] , "SIGABRT" ) ;
1816+ }
17751817 _ => panic ! ( "unexpected crash_typ {crash_typ}" ) ,
17761818 }
17771819}
@@ -1906,6 +1948,10 @@ fn assert_telemetry_message(crash_telemetry: &[u8], crash_typ: &str) {
19061948 "unhandled_exception" => {
19071949 // Unhandled exceptions have no signal info tags
19081950 }
1951+ "assert_fail" => {
1952+ assert ! ( tags. contains( "si_signo_human_readable:SIGABRT" ) , "{tags:?}" ) ;
1953+ assert ! ( tags. contains( "si_signo:6" ) , "{tags:?}" ) ;
1954+ }
19091955 _ => panic ! ( "{crash_typ}" ) ,
19101956 }
19111957
0 commit comments