Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions compiler-rt/lib/fuzzer/FuzzerDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,9 @@ static int RunInMultipleProcesses(const std::vector<std::string> &Args,
return HasErrors ? 1 : 0;
}

// Fuchsia needs to do some book checking before starting the RssThread,
// so it has its own implementation.
#if !LIBFUZZER_FUCHSIA
static void RssThread(Fuzzer *F, size_t RssLimitMb) {
while (true) {
SleepSeconds(1);
Expand All @@ -321,6 +324,7 @@ static void StartRssThread(Fuzzer *F, size_t RssLimitMb) {
std::thread T(RssThread, F, RssLimitMb);
T.detach();
}
#endif

int RunOneTest(Fuzzer *F, const char *InputFilePath, size_t MaxLen) {
Unit U = FileToVector(InputFilePath);
Expand Down
60 changes: 57 additions & 3 deletions compiler-rt/lib/fuzzer/FuzzerUtilFuchsia.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ void ExitOnErr(zx_status_t Status, const char *Syscall) {
}

void AlarmHandler(int Seconds) {
// Signal the alarm thread started.
ExitOnErr(_zx_object_signal(SignalHandlerEvent, 0, ZX_USER_SIGNAL_0),
"_zx_object_signal AlarmHandler");
while (true) {
SleepSeconds(Seconds);
Fuzzer::StaticAlarmCallback();
Expand Down Expand Up @@ -282,6 +285,7 @@ void CrashHandler() {
Self, ZX_EXCEPTION_CHANNEL_DEBUGGER, &Channel.Handle),
"_zx_task_create_exception_channel");

// Signal the crash thread started.
ExitOnErr(_zx_object_signal(SignalHandlerEvent, 0, ZX_USER_SIGNAL_0),
"_zx_object_signal");

Expand Down Expand Up @@ -385,10 +389,49 @@ void StopSignalHandler() {
_zx_handle_close(SignalHandlerEvent);
}

void RssThread(Fuzzer *F, size_t RssLimitMb) {
// Signal the rss thread started.
//
// We must wait for this thread to start because we could accidentally suspend
// it while the crash handler is attempting to handle the
// ZX_EXCP_THREAD_STARTING exception. If the crash handler is suspended by the
// lsan machinery, then there's no way for this thread to indicate it's
// suspended because it's blocked on waiting for the exception to be handled.
ExitOnErr(_zx_object_signal(SignalHandlerEvent, 0, ZX_USER_SIGNAL_0),
"_zx_object_signal rss");
while (true) {
SleepSeconds(1);
size_t Peak = GetPeakRSSMb();
if (Peak > RssLimitMb)
F->RssLimitCallback();
}
}

} // namespace

void StartRssThread(Fuzzer *F, size_t RssLimitMb) {
// Set up the crash handler and wait until it is ready before proceeding.
assert(SignalHandlerEvent == ZX_HANDLE_INVALID);
ExitOnErr(_zx_event_create(0, &SignalHandlerEvent), "_zx_event_create");

if (!RssLimitMb)
return;
std::thread T(RssThread, F, RssLimitMb);
T.detach();

// Wait for the rss thread to start.
ExitOnErr(_zx_object_wait_one(SignalHandlerEvent, ZX_USER_SIGNAL_0,
ZX_TIME_INFINITE, nullptr),
"_zx_object_wait_one rss");
ExitOnErr(_zx_object_signal(SignalHandlerEvent, ZX_USER_SIGNAL_0, 0),
"_zx_object_signal rss clear");
}

// Platform specific functions.
void SetSignalHandler(const FuzzingOptions &Options) {
assert(SignalHandlerEvent != ZX_HANDLE_INVALID &&
"This should've been setup by StartRssThread.");

// Make sure information from libFuzzer and the sanitizers are easy to
// reassemble. `__sanitizer_log_write` has the added benefit of ensuring the
// DSO map is always available for the symbolizer.
Expand All @@ -404,6 +447,20 @@ void SetSignalHandler(const FuzzingOptions &Options) {
if (Options.HandleAlrm && Options.UnitTimeoutSec > 0) {
std::thread T(AlarmHandler, Options.UnitTimeoutSec / 2 + 1);
T.detach();

// Wait for the alarm thread to start.
//
// We must wait for this thread to start because we could accidentally
// suspend it while the crash handler is attempting to handle the
// ZX_EXCP_THREAD_STARTING exception. If the crash handler is suspended by
// the lsan machinery, then there's no way for this thread to indicate it's
// suspended because it's blocked on waiting for the exception to be
// handled.
ExitOnErr(_zx_object_wait_one(SignalHandlerEvent, ZX_USER_SIGNAL_0,
ZX_TIME_INFINITE, nullptr),
"_zx_object_wait_one alarm");
ExitOnErr(_zx_object_signal(SignalHandlerEvent, ZX_USER_SIGNAL_0, 0),
"_zx_object_signal alarm clear");
}

// Options.HandleInt and Options.HandleTerm are not supported on Fuchsia
Expand All @@ -413,9 +470,6 @@ void SetSignalHandler(const FuzzingOptions &Options) {
!Options.HandleFpe && !Options.HandleAbrt && !Options.HandleTrap)
return;

// Set up the crash handler and wait until it is ready before proceeding.
ExitOnErr(_zx_event_create(0, &SignalHandlerEvent), "_zx_event_create");

SignalHandler = std::thread(CrashHandler);
zx_status_t Status = _zx_object_wait_one(SignalHandlerEvent, ZX_USER_SIGNAL_0,
ZX_TIME_INFINITE, nullptr);
Expand Down
Loading