@@ -68,6 +68,9 @@ void ExitOnErr(zx_status_t Status, const char *Syscall) {
6868}
6969
7070void 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" );
7174 while (true ) {
7275 SleepSeconds (Seconds);
7376 Fuzzer::StaticAlarmCallback ();
@@ -282,6 +285,7 @@ void CrashHandler() {
282285 Self, ZX_EXCEPTION_CHANNEL_DEBUGGER, &Channel.Handle ),
283286 " _zx_task_create_exception_channel" );
284287
288+ // Signal the crash thread started.
285289 ExitOnErr (_zx_object_signal (SignalHandlerEvent, 0 , ZX_USER_SIGNAL_0),
286290 " _zx_object_signal" );
287291
@@ -385,10 +389,49 @@ void StopSignalHandler() {
385389 _zx_handle_close (SignalHandlerEvent);
386390}
387391
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+
388410} // namespace
389411
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+
390430// Platform specific functions.
391431void SetSignalHandler (const FuzzingOptions &Options) {
432+ assert (SignalHandlerEvent != ZX_HANDLE_INVALID &&
433+ " This should've been setup by StartRssThread." );
434+
392435 // Make sure information from libFuzzer and the sanitizers are easy to
393436 // reassemble. `__sanitizer_log_write` has the added benefit of ensuring the
394437 // DSO map is always available for the symbolizer.
@@ -404,6 +447,20 @@ void SetSignalHandler(const FuzzingOptions &Options) {
404447 if (Options.HandleAlrm && Options.UnitTimeoutSec > 0 ) {
405448 std::thread T (AlarmHandler, Options.UnitTimeoutSec / 2 + 1 );
406449 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" );
407464 }
408465
409466 // Options.HandleInt and Options.HandleTerm are not supported on Fuchsia
@@ -413,9 +470,6 @@ void SetSignalHandler(const FuzzingOptions &Options) {
413470 !Options.HandleFpe && !Options.HandleAbrt && !Options.HandleTrap )
414471 return ;
415472
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-
419473 SignalHandler = std::thread (CrashHandler);
420474 zx_status_t Status = _zx_object_wait_one (SignalHandlerEvent, ZX_USER_SIGNAL_0,
421475 ZX_TIME_INFINITE, nullptr );
0 commit comments