@@ -68,6 +68,9 @@ void ExitOnErr(zx_status_t Status, const char *Syscall) {
68
68
}
69
69
70
70
void AlarmHandler (int Seconds) {
71
+ // Signal the alarm thread started.
72
+ ExitOnErr (_zx_object_signal (SignalHandlerEvent, 0 , ZX_USER_SIGNAL_0),
73
+ " _zx_object_signal alarm" );
71
74
while (true ) {
72
75
SleepSeconds (Seconds);
73
76
Fuzzer::StaticAlarmCallback ();
@@ -282,6 +285,7 @@ void CrashHandler() {
282
285
Self, ZX_EXCEPTION_CHANNEL_DEBUGGER, &Channel.Handle ),
283
286
" _zx_task_create_exception_channel" );
284
287
288
+ // Signal the crash thread started.
285
289
ExitOnErr (_zx_object_signal (SignalHandlerEvent, 0 , ZX_USER_SIGNAL_0),
286
290
" _zx_object_signal" );
287
291
@@ -385,10 +389,49 @@ void StopSignalHandler() {
385
389
_zx_handle_close (SignalHandlerEvent);
386
390
}
387
391
392
+ void RssThread (Fuzzer *F, size_t RssLimitMb) {
393
+ // Signal the rss thread started.
394
+ //
395
+ // We must wait for this thread to start because we could accidentally suspend
396
+ // it while the crash handler is attempting to handle the
397
+ // ZX_EXCP_THREAD_STARTING exception. If the crash handler is suspended by the
398
+ // lsan machinery, then there's no way for this thread to indicate it's
399
+ // suspended because it's blocked on waiting for the exception to be handled.
400
+ ExitOnErr (_zx_object_signal (SignalHandlerEvent, 0 , ZX_USER_SIGNAL_0),
401
+ " _zx_object_signal rss" );
402
+ while (true ) {
403
+ SleepSeconds (1 );
404
+ size_t Peak = GetPeakRSSMb ();
405
+ if (Peak > RssLimitMb)
406
+ F->RssLimitCallback ();
407
+ }
408
+ }
409
+
388
410
} // namespace
389
411
412
+ void StartRssThread (Fuzzer *F, size_t RssLimitMb) {
413
+ // Set up the crash handler and wait until it is ready before proceeding.
414
+ assert (SignalHandlerEvent == ZX_HANDLE_INVALID);
415
+ ExitOnErr (_zx_event_create (0 , &SignalHandlerEvent), " _zx_event_create" );
416
+
417
+ if (!RssLimitMb)
418
+ return ;
419
+ std::thread T (RssThread, F, RssLimitMb);
420
+ T.detach ();
421
+
422
+ // Wait for the rss thread to start.
423
+ ExitOnErr (_zx_object_wait_one (SignalHandlerEvent, ZX_USER_SIGNAL_0,
424
+ ZX_TIME_INFINITE, nullptr ),
425
+ " _zx_object_wait_one rss" );
426
+ ExitOnErr (_zx_object_signal (SignalHandlerEvent, ZX_USER_SIGNAL_0, 0 ),
427
+ " _zx_object_signal rss clear" );
428
+ }
429
+
390
430
// Platform specific functions.
391
431
void SetSignalHandler (const FuzzingOptions &Options) {
432
+ assert (SignalHandlerEvent != ZX_HANDLE_INVALID &&
433
+ " This should've been setup by StartRssThread." );
434
+
392
435
// Make sure information from libFuzzer and the sanitizers are easy to
393
436
// reassemble. `__sanitizer_log_write` has the added benefit of ensuring the
394
437
// DSO map is always available for the symbolizer.
@@ -404,6 +447,20 @@ void SetSignalHandler(const FuzzingOptions &Options) {
404
447
if (Options.HandleAlrm && Options.UnitTimeoutSec > 0 ) {
405
448
std::thread T (AlarmHandler, Options.UnitTimeoutSec / 2 + 1 );
406
449
T.detach ();
450
+
451
+ // Wait for the alarm thread to start.
452
+ //
453
+ // We must wait for this thread to start because we could accidentally
454
+ // suspend it while the crash handler is attempting to handle the
455
+ // ZX_EXCP_THREAD_STARTING exception. If the crash handler is suspended by
456
+ // the lsan machinery, then there's no way for this thread to indicate it's
457
+ // suspended because it's blocked on waiting for the exception to be
458
+ // handled.
459
+ ExitOnErr (_zx_object_wait_one (SignalHandlerEvent, ZX_USER_SIGNAL_0,
460
+ ZX_TIME_INFINITE, nullptr ),
461
+ " _zx_object_wait_one alarm" );
462
+ ExitOnErr (_zx_object_signal (SignalHandlerEvent, ZX_USER_SIGNAL_0, 0 ),
463
+ " _zx_object_signal alarm clear" );
407
464
}
408
465
409
466
// Options.HandleInt and Options.HandleTerm are not supported on Fuchsia
@@ -413,9 +470,6 @@ void SetSignalHandler(const FuzzingOptions &Options) {
413
470
!Options.HandleFpe && !Options.HandleAbrt && !Options.HandleTrap )
414
471
return ;
415
472
416
- // Set up the crash handler and wait until it is ready before proceeding.
417
- ExitOnErr (_zx_event_create (0 , &SignalHandlerEvent), " _zx_event_create" );
418
-
419
473
SignalHandler = std::thread (CrashHandler);
420
474
zx_status_t Status = _zx_object_wait_one (SignalHandlerEvent, ZX_USER_SIGNAL_0,
421
475
ZX_TIME_INFINITE, nullptr );
0 commit comments