This is an archive of the discontinued LLVM Phabricator instance.

[Sanitizer] Rework BufferedStackTrace::Unwind (part 1)
AbandonedPublic

Authored by yln on Feb 21 2019, 6:17 PM.

Details

Summary

In a previous revision (https://reviews.llvm.org/D58156) I fixed a few
failing tests on Darwin involving stack printing.

The underlying issue has to do with stack unwinding. We have the notion
of a slow and a fast unwinder. Linux has both, on Darwin only the fast
unwinder is available.

Considering this, the current API is hard to use correctly.

BufferedStackTrace::Unwind(u32 max_depth, uptr pc, uptr bp, void *context,
                           uptr stack_top, uptr stack_bottom,
                           bool request_fast_unwind)

The only thing the slow unwinder needs to work is pc. It can also take
an optional context. The fast unwinder additionally requires
bp,stack_top, stack_bottom. The context is not applicable to the
fast unwinder.

The semantics of request_fast_unwind is really only a "request" to use
the fast unwinder. On platforms that only support one kind of unwinder
it is essentially ignored.

This means that code like below doesn't work on Darwin.

bool fast = common_flags()->fast_unwind_on_fatal;
if (fast)
  GetThreadStackTopAndBottom(..., &top, &bottom);

stack.Unwind(..., top, bottom, fast);
// May use fast unwinder, but top and bottom haven't been provided.

// Even the following is broken
stack.Unwind(..., 0, 0, false);

The function StackTrace::WillUseFastUnwind was introduced to remedy
this. In my last patch, I applied it some places that caused test
failures. This patch adds a few more calls.

However, ultimately BufferedStackTrace::Unwind is not a good API. (I
guess it just grew more complex over time.) It tries to hide which
unwinder is used, but to use it correctly the caller needs to be aware
which unwinder is going to be used. Its set of parameters is the union
of required arguments of both unwinders.

This patch removes Unwind and directly calls the fast or slow unwind
functions. This change (part 1) is purely mechanical. In a follow-up I
want to try to cleanup the call sites. Maybe it is possible to hide most
of the details behind yet another macro.

rdar://problem/48177534

Event Timeline

yln created this revision.Feb 21 2019, 6:17 PM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptFeb 21 2019, 6:17 PM
Herald added subscribers: llvm-commits, Restricted Project, jdoerfert and 4 others. · View Herald Transcript

ninja check-sanitizer passes on my Mac and Linux VM (Ubuntu 18). I would appreciate if someone can test this on their Windows machine!

vitalybuka added inline comments.Feb 22 2019, 10:53 AM
compiler-rt/lib/ubsan/ubsan_diag_standalone.cc
25

Would be nice to have separate NFC patch for stuff like removing _sanitizer::

31

Could you also make another NFC patch for:
Unwind(... bool) -> FastUnwind/SlowUnwind

34

SlowUnwindStack -> just SlowUnwind
Word Stack is redundant there at it's a member of the StackTrace

vitalybuka added inline comments.Feb 22 2019, 10:58 AM
compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h
61

Another patch is here...
Please extract tiny patches for whatever the rest of the patch irrelevant.

yln abandoned this revision.Feb 22 2019, 11:24 AM

As requested, I will split this up into smaller patches.
First one is here: https://reviews.llvm.org/D58550