This is an archive of the discontinued LLVM Phabricator instance.

[LibFuzzer] Fix sending SIGALRM to main thread under Mac OSX
AbandonedPublic

Authored by delcypher on May 19 2016, 9:51 PM.

Details

Reviewers
kcc
kubamracek
Summary

[LibFuzzer] Fix sending SIGALRM signal to main thread on Mac OSX.

This replaces the Linux only implementation with an implementation that
relies on pthread_kill() which is more portable. For this to work
the Fuzzer now records the thread it was created in (presumably the main
thread).

This isn't an ideal fix because now we have a pthreads dependency
but arguably if we wanted portability we shouldn't be using signals
either.

Diff Detail

Event Timeline

delcypher updated this revision to Diff 57891.May 19 2016, 9:51 PM
delcypher retitled this revision from to [LibFuzzer] Fix sending SIGALRM to main thread under Mac OSX.
delcypher updated this object.
delcypher added reviewers: kcc, kubamracek.
delcypher added subscribers: llvm-commits, kcc.
kcc edited edge metadata.May 19 2016, 10:28 PM

dependency on -lpthread would be unfortunate...
And I don't like the current code either.
Let me rethink this one.
This may be solved by printing and Exiting_ in the getrusage thread --
the only question is how to avoid the race on CurrentUnitData/CurrentUnitSize w/o having to use a Mutex.

Want to try this?

kcc added a comment.May 19 2016, 10:33 PM

Or maybe just grab a mutex around CurrentUnitData/CurrentUnitSize
and see how much it affects performance on e.g. test/FullCoverageSetTest.cpp
If not much, just use a mutex.

@kcc : Just to note I think you already have an implicit pthreads dependency. The CMakeLists.txt file seems to link
against it also (side note: why are the flags only being set for the CMake build type being RELEASE?).

I didn't need to pass -lpthread when building (I'm building independently of LLVM's CMake build system) on my system. I suspect that std::thread might already be using pthreads internally.

kcc added a comment.May 19 2016, 10:50 PM

@kcc : Just to note I think you already have an implicit pthreads dependency.

Very likely. But it's more like I want to stay away from including pthread.h, if possible.
And also, the current way of dying on OOMs is less portable than just dying inside the getrusage thread.

The CMakeLists.txt file seems to link
against it also (side note: why are the flags only being set for the CMake build type being RELEASE?).

For no good reason, feel free to fix that.

I didn't need to pass -lpthread when building (I'm building independently of LLVM's CMake build system) on my system. I suspect that std::thread might already be using pthreads internally.

Note that the majority of users use libFuzzer outside of the llvm build system,
will they need to add -lphtread to their build rules?

delcypher added a comment.EditedMay 19 2016, 10:52 PM

@kcc

This may be solved by printing and Exiting_ in the getrusage thread --
the only question is how to avoid the race on CurrentUnitData/CurrentUnitSize w/o having to use a Mutex.

Want to try this?

I'll take a look tomorrow. I need to first take a look at how CurrentUnitData and CurrentUnitSize are being used and consequently where they need to locked.

Just a thought. Why not just be single threaded and call getrusage() after every iteration of LLVMFuzzerTestOneInput(...)? It will mean for long running and non-terminating runs of LLVMFuzzerTestOneInput(...) we might not (or ever) detect OOM but it would avoid the complexity and the races. Personally I feel like detecting OOM should really be done externally using something like cgroups, but maybe that's a bad idea.

delcypher added a comment.EditedMay 19 2016, 10:56 PM

Note that the majority of users use libFuzzer outside of the llvm build system,
will they need to add -lphtread to their build rules?

I found that I didn't need to under OSX or Linux. Note I didn't really test under Linux properly as something about my distro's clang is broken (__sanitizer_get_coverage_pc_buffer seems to be NULL at runtime). I need to rebuild on trunk and test more thoroughly.

kcc added a comment.May 19 2016, 10:59 PM

@kcc

This may be solved by printing and Exiting_ in the getrusage thread --

the only question is how to avoid the race on CurrentUnitData/CurrentUnitSize w/o having to use a Mutex.

Want to try this?

I'll take a look tomorrow. I need to first take a look at how CurrentUnitData and CurrentUnitSize are being used and consequently where they need to locked.

CurrentUnitData is used to dump the reproducer on disk.

Just a thought. Why not just be single threaded and call getrusage() after every iteration of LLVMFuzzerTestOneInput(...)? It will mean for long running and non-terminating runs of LLVMFuzzerTestOneInput(...) we might not (or ever) detect OOM but it would avoid the complexity and the races. Personally I feel like detecting OOM should really be done externally using something like cgroups, but maybe that's a bad idea.

One of the two reasons for detecting OOMs in libFuzzer is to not let it kill your machine.
You can't do it by checking getrusage after your machine has died.

cgroups are hard to set up, you should not expect every libFuzzer user to do it.
AFAICT, they also require sudo (no?)
Ideally we would have kernel support for RLIMIT_RSS, but there is no such thing today. :(

kcc added a comment.May 26 2016, 3:54 PM

FYI: am working on refactoring this part, hold on your changes please...

@kcc:

FYI: am working on refactoring this part, hold on your changes please...

Thanks for the info. I took a break from doing this as I wanted to make it possible to run the tests on OSX first. Glad to hear you are taking a look at it.

kcc added a comment.May 26 2016, 6:01 PM

I think I've fixed this in r270945.
This part is tricky because it involves both threads and signals,
so I tried to make it simpler.

delcypher abandoned this revision.Jun 3 2016, 11:32 AM

This change isn't needed any more.