Comment #3 on issue 345 by [email protected]: Use Linux
madvise(MADV_DONTDUMP) to exclude ASan shadow regions from core dumps
https://code.google.com/p/address-sanitizer/issues/detail?id=345
Regarding ASAN_OPTIONS=unmap_shadow_on_exit=1:
No, I did not previously try that. It's not listed on the Wiki page of
known flags <https://code.google.com/p/address-sanitizer/wiki/Flags> and I
did not notice it while reading the libsanitizer source to implement the
madvise patch. However, now that you pointed it out, I tried it and it
does not seem to do what I want. I see that it is supported in both
gcc-4.8 and gcc-4.9. To test it, I used a program where main() calls
abort(), to simulate a program which dies due to failing an internal
consistency check, as opposed to dying because AddressSanitizer found a
memory misuse. I compiled it with both gcc-4.8, which uses the stock
libsanitizer, and with gcc-4.9, which has my proof of concept madvise patch
applied.
When using the stock libsanitizer of gcc-4.8 with
ASAN_OPTIONS=unmap_shadow_on_exit=1,disable_core=0 ./abort48, the program
goes to 100% CPU in system mode and ultimately generates an apparently 14T
core (actual size per du: 3.4M). I also tried using a colon to separate
the options, with the same result. The core took about 2 minutes to write,
despite its effective very small size.
When using the locally patched libsanitizer of gcc-4.9 with
ASAN_OPTIONS=disable_core=0 ./abort49, the program dumps an apparently 48M
core (actual size per du: 2.4M) and exits almost instantly.
I also tried a test program which writes to *(int*)nullptr, to trigger an
AddressSanitizer trap. In that case, I needed to add abort_on_error=1,
otherwise no core file was generated after AddressSanitizer trapped the
SIGSEGV. This is a bit counterintuitive, since an unsanitized program
would have dumped core on a null pointer write, but an
AddressSanitizer-instrumented program requires both disable_core=0 *and*
abort_on_error=1 to dump core on a null pointer write. I expected
abort_on_error=1 was only needed if I wanted to abort on errors found
specific to AddressSanitizer (redzone, malloc/delete mismatch, etc.) and
that regular errors were affected only by disable_core. Using
abort_on_error=1 here also generates a core file that is recorded as an
ABRT (gdb says "Program terminated with signal SIGABRT, Aborted."), which
while technically true, is misleading since the abort happened in response
to a SIGSEGV. The frame where the SIGSEGV happened seems to be well
recorded, so the core is still usable for debugging.
- Using ASAN_OPTIONS=disable_core=0 ./segv48, I get an AddressSanitizer
report, no core file, and immediate return to shell.
- Using ASAN_OPTIONS=disable_core=0:abort_on_error=1 ./segv48, I get the
long stall and 14T core file, returning to the shell after about 2 minutes.
- Using ASAN_OPTIONS=disable_core=0:unmap_shadow_on_exit=1 ./segv48, I get
no core file and an immediate return to shell.
- Using
ASAN_OPTIONS=disable_core=0:abort_on_error=1:unmap_shadow_on_exit=1 ./segv48,
I get an abort and immediate small core file.
Thus, I understand what you were hoping to see when you suggested
unmap_shadow_on_exit=1, but it does not solve the problem fully, since it
only works on scenarios where AddressSanitizer triggered the abort, but not
on scenarios where the program called abort() on its own (nor scenarios
with less common core-generating signals, such as SIGQUIT). Marking the
tables as not-dumpable ensures that they are not written regardless of why
the kernel writes a core dump.
--
You received this message because this project is configured to send all
issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings
--
You received this message because you are subscribed to the Google Groups
"address-sanitizer" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.