This is an archive of the discontinued LLVM Phabricator instance.

[sanitizer] Stop unwinding the stack when a close-to-zero PC is found
ClosedPublic

Authored by kubamracek on Nov 13 2015, 7:02 AM.

Details

Summary

On OS X, we often get stack trace in a report that ends with a 0x0 frame:

=================================================================
==56615==ERROR: AddressSanitizer: heap-use-after-free on address 0x60200000eed0 at pc 0x00010aa33359 bp 0x7fff552057f0 sp 0x7fff552023a0
READ of size 2 at 0x60200000eed0 thread T0
#0 0x10aa33358 in printf_common(void*, char const*, __va_list_tag*) sanitizer_common_interceptors_format.inc:545
#1 0x10aa31e24 in wrap_vprintf sanitizer_common_interceptors.inc:1099
#2 0x7fff8c4375ac in start (libdyld.dylib+0x35ac)
#3 0x0  (<unknown module>)

To get rid of it, let's trim the stack trace when we find a close-to-zero value, which is obviously not a valid PC.

Diff Detail

Event Timeline

kubamracek updated this revision to Diff 40148.Nov 13 2015, 7:02 AM
kubamracek retitled this revision from to [sanitizer] Stop unwinding the stack when a close-to-zero PC is found.
kubamracek updated this object.
kubamracek added reviewers: kcc, samsonov, glider, dvyukov.
glider accepted this revision.Nov 13 2015, 7:16 AM
glider edited edge metadata.

Makes sense, LGTM

lib/sanitizer_common/sanitizer_stacktrace.h
21

OOC, have you seen values other than 0x0 for the bottom frame?

This revision is now accepted and ready to land.Nov 13 2015, 7:16 AM
samsonov requested changes to this revision.Nov 13 2015, 11:48 AM
samsonov edited edge metadata.

This doesn't look like a good change. Why is this fixed only in fast, but not in slow unwinder? Are you sure we should consider any address 0x1000 as bad, not only 0x0?

This revision now requires changes to proceed.Nov 13 2015, 11:48 AM

This doesn't look like a good change. Why is this fixed only in fast, but not in slow unwinder? Are you sure we should consider any address 0x1000 as bad, not only 0x0?

Ignoring 0x0 is not enough. The result 0x0 printed in the stack trace is actually a 0x1 at the bottom of the stack (because we subtract 1 from return addresses in GetPreviousInstructionPc).

This doesn't look like a good change. Why is this fixed only in fast, but not in slow unwinder? Are you sure we should consider any address 0x1000 as bad, not only 0x0?

It should be safe to assume that the first kPageSize bytes of the address space (not necessarily 0x1000) do not contain any code.

kubamracek updated this revision to Diff 40259.Nov 16 2015, 2:25 AM
kubamracek edited edge metadata.

Updating patch.

So how about doing the same in the slow unwinder?

kubamracek updated this revision to Diff 40267.Nov 16 2015, 3:00 AM
kubamracek edited edge metadata.

Adding the check into slow unwinder as well.

glider accepted this revision.Nov 16 2015, 3:21 AM
glider edited edge metadata.

I think this is fine, but let's wait for Alexey.

Please add a test case to lib/sanitizer_common/tests/sanitizer_stacktrace_test.cc
I'm slightly worried about extra function call you add to each fast stack unwind. Maybe it makes sense to inline that function in the header.

kubamracek updated this revision to Diff 58101.May 23 2016, 8:48 AM
kubamracek edited edge metadata.

Adding a unit test. Changing GetPageSizeCached into an inlined function.

Is this okay to land?

dvyukov accepted this revision.Jun 27 2016, 4:00 AM
dvyukov edited edge metadata.
This revision was automatically updated to reflect the committed changes.