TSan and C++ exceptions

104 views
Skip to first unread message

Kuba Brecka

unread,
Oct 21, 2016, 6:28:09 PM10/21/16
to thread-sanitizer

I know there are known issues with TSan when C++ exceptions are used.  I'm investigating what would it take to properly start supporting them.  Basically, the thing I care about is the shadow stack, which gets broken when a call to __tsan_func_exit is missed.

I found this abandoned patch by Dmitry, https://reviews.llvm.org/D10740, which seems to be a promising way, but it also seems to have a few problems.  Is this approach (adding landingpads in the IR pass) the best way to do that?  What about doing this at Clang level, would that be easier?  Or is there some other possible solution (e.g. how longjmp is handled)?  We could e.g. change __tsan_func_enter to return a "token" which would then be passed to the matching __tsan_func_exit -- if the token doesn't match the top of the shadow stack, we would unwind to "fix" the stack.  Opinions?  Suggestions?

Thanks,
Kuba

Dmitry Vyukov

unread,
Oct 30, 2016, 8:02:49 PM10/30/16
to Kuba Brecka, thread-sanitizer, Anna Zaks
Hi,

Sorry for delays, I am OOO and traveling.

Re your patch "tsan: support C++ exceptions"
(https://reviews.llvm.org/D10740). It has several problems:
1. It will not fix the problem if we don't return from the function
that catches an exception. Consider that we catch an exception and
then call throwing function again without returning. First, we will
have bogus stacks in reports since we don't remove stale frames from
shadow stack. Second, if this happens in a loop we will overflow
shadow stack.
2. Identifying frames by PC is wrong in presence of indirect calls.
Consider that function A makes an indirect call to B, then B calls A,
then A makes indirect call to C (at the same PC). The stack looks as
A->B->A->C. Now C throws and B catches an exception. Exit from B will
obtain return PC in A and unwind shadow stack up to it. However, it
will find the wrong A -- the second one, while it was called from the
first A.
3. FWIW it slows down normal execution.

2 can be fixed if we use SP as frame identifier. However, we still
have problem 1 and 3. Plus we we have doubled memory consumption for
shadow stack as we need to remember both PC and SP.

Emitting cleanup landing pads (https://reviews.llvm.org/D10740) looks
much more reliable to me, because we are playing by the exception
rules rather than trying to hack something on the side. And it also
does not slow down execution, nor increase memory consumption.
But it turned out to be not trivial as expected initially, and I never
had time to finish it. If you want to pick it up, it would be great.
Exceptions are an important part of C++. Reid gave some hints in the
comments. And you can also grep llvm code for CreateLandingPad and
__gcc_personality_v0.
Reply all
Reply to author
Forward
0 new messages