[llvm-bugs] [Bug 43698] New: TSAN provides incorrect context to signal handler for async SIGPROF

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Oct 17 05:42:51 PDT 2019


https://bugs.llvm.org/show_bug.cgi?id=43698

            Bug ID: 43698
           Summary: TSAN provides incorrect context to signal handler for
                    async SIGPROF
           Product: compiler-rt
           Version: unspecified
          Hardware: PC
                OS: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: tsan
          Assignee: unassignedbugs at nondot.org
          Reporter: petermarshall at chromium.org
                CC: llvm-bugs at lists.llvm.org

Here's the code I'm talking about:
https://github.com/llvm/llvm-project/blob/9917c76107f827ec2ac19cbd5a42939ddd3bd2be/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp#L2016

TSAN seems to differentiate between sync and async signals. SIGPROF is not
listed as a sync signal in is_sync_signal() - this seems correct to me. But
here's the problem. rtl_generic_sighandler() delays the sending of async
signals (from other threads). It does this by copying the ctx struct into
pending_signals. It then continues running the target program, and at certain
points later it will deliver pending async signals. But the context that it
delivers to the user-installed signal handler is the one that it copied at the
time of the actual signal. This context is now stale, as the target program
continued to run in the meantime. 

In V8 we have a background thread which sends SIGPROF to the main thread via
pthread_kill() to trigger a sample in our sampling profiler. In the signal
handler we use the context to unwind the stack and later symbolize the return
addresses we take from the stack in order to get a stack trace of JavaScript
code.

We found through debugging that this context is wrong when we compile with
TSAN, and this causes us to read garbage values off the stack which causes our
stack walking to fail. By wrong I mean, we walk the stack but discover we
aren't in the code that contains the PC provided by the context argument.

There are tests currently in LLVM e.g. compiler-rt/test/tsan/signal_errno.cpp
which sends a SIGPROF from another thread, but the handler does not rely on the
contents of the context argument being correct. None of the tests check the
context argument which is I think why this bug has gone unnoticed.

Repro:
A test/repro would basically look like compiler-rt/test/tsan/signal_thread.cpp
except that in the handler, we somehow need to verify that the context argument
relates to the current active stack and not a previous snapshot of the stack,
taken at the time the signal was actually received.
I'm not sure exactly how to test that, maybe someone has a suggestion.

Expected result:
The context argument should always relate to the current stack/registers when
the signal handler is received, not a past snapshot.

Affected platforms/versions:
I think the bug affects Linux and Mac and affects all versions.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20191017/b7eb8130/attachment.html>


More information about the llvm-bugs mailing list