Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TSAN does not handle siglongjmp(3) jumping out of signal handler #482

Closed
ramosian-glider opened this issue Sep 1, 2015 · 6 comments
Closed

Comments

@ramosian-glider
Copy link
Member

Originally reported on Google Code with ID 75

short story:

TSAN crashes on my program involving synchronous SIGSEGV handler and siglongjmp() jumping
out of it with the following message:

    FATAL: ThreadSanitizer CHECK failed: .../tsan_interceptors.cc:1644 "((thr->in_signal_handler))
== ((false))" (0x1, 0x0)

details below:

What steps will reproduce the problem?

1. Compile attached tsansig.c with -fsanitize=thread, e.g.
    $ gcc -g -Wall -fsanitize=thread -pie -fPIC tsansig.c
    $ clang -g -Wall -fsanitize=thread tsansig.c

2. Run the program
    $ ./a.out

What is the expected output? What do you see instead?

expected output is (does happen without sanitizing at all, and with ASAN)

    ((int *)NULL)[0] = 0 faulted ok
    ((int *)NULL)[1] = 1 faulted ok
    ((int *)NULL)[3] = 1 faulted ok

with TSAN I get:

# gcc
((int *)NULL)[0] = 0 faulted ok
FATAL: ThreadSanitizer CHECK failed: ../../../../src/libsanitizer/tsan/tsan_interceptors.cc:1644
"((thr->in_signal_handler)) == ((false))" (0x1, 0x0)
    #0 <null> <null>:0 (libtsan.so.0+0x000000064c1c)
    #1 <null> <null>:0 (libtsan.so.0+0x000000064cf2)
    #2 __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long,
unsigned long long) <null>:0 (libtsan.so.0+0x000000069323)
    #3 <null> <null>:0 (libtsan.so.0+0x0000000330f2)
    #4 <null> <null>:0 (libc.so.6+0x0000000350ef)
    #5 __tsan_write4 <null>:0 (libtsan.so.0+0x00000002ec92)
    #6 main /home/kirr/tmp/trashme/tsansig.c:61 (a.out+0x000000000e5a)
    #7 __libc_start_main <null>:0 (libc.so.6+0x000000021b44)
    #8 <null> <null>:0 (a.out+0x000000000b38)
    #9 <null> <null>:0 (0x000000000000)

# clang
((int *)NULL)[0] = 0 faulted ok
FATAL: ThreadSanitizer CHECK failed: /tmp/buildd/llvm-toolchain-3.4-3.4.2/projects/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc:1644
"((thr->in_signal_handler)) == ((false))" (0x1, 0x0)
    #0 __tsan::PrintCurrentStackSlow() ??:0 (exe+0x00000009f9df)
    #1 __tsan::TsanCheckFailed(char const*, int, char const*, unsigned long long, unsigned
long long) ??:0 (exe+0x00000009f9b3)
    #2 __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long,
unsigned long long) ??:0 (exe+0x0000000386a1)
    #3 rtl_sighandler(int) tsan_interceptors.o:0 (exe+0x000000055712)
    #4 _L_unlock_13 ??:0 (libpthread.so.0+0x00000000f8cf)
    #5 __tsan_write4 ??:0 (exe+0x00000009bb47)
    #6 main /home/kirr/tmp/trashme/tsansig.c:61 (exe+0x0000000a5539)
    #7 __libc_start_main /home/aurel32/glibc/glibc-2.19/csu/libc-start.c:287 (libc.so.6+0x000000021b44)
    #8 _start ??:0 (exe+0x0000000a51bc)
    #9 <null> <null>:0 (0x000000000000)


What version of the product are you using? On what operating system?

OS is Debian GNU/Linux testing on x86_64 with current gcc and clang:

$ uname -a
Linux teco 3.14-2-amd64 #1 SMP Debian 3.14.15-2 (2014-08-09) x86_64 GNU/Linux

$ gcc --version
gcc (Debian 4.9.1-11) 4.9.1

$ clang --version
Debian clang version 3.4.2-8 (tags/RELEASE_34/dot2-final) (based on LLVM 3.4.2)
Target: x86_64-pc-linux-gnu
Thread model: posix



Please provide any additional information below.

The problem, it seems, is caused by that siglongjmp interceptor does not adjust thr->in_signal_handler
to state that could be saved in sigsetjmp interceptor.

As a result rtl_generic_sighandler() first increments thr->in_signal_handler, then
calls the handler, then wants to decrement thr->in_signal_handler, but oops, if we
jump out of signal handler, thr->in_signal_handler is left not decremented.

And on next entry to TSAN sighanl handler that check fires.

I can't say for sure whether git rev 4e992b94 (tsan: restructure signal handling to
allow recursive handling, dvyukov, 2014-09-02) for compiler-rt fixed it, but it seems
no, because it deals with orthogonal issue and LongJmp() code has not been changed.

Thanks beforehand,
Kirill


Reported by kirill.smelkov on 2014-09-10 10:57:29


- _Attachment: [tsansig.c](https://storage.googleapis.com/google-code-attachments/thread-sanitizer/issue-75/comment-0/tsansig.c)_
@ramosian-glider
Copy link
Member Author

Thanks for reporting the issue.
I will test on tip and fix it if it is still broken.

Reported by dvyukov@google.com on 2014-09-10 20:09:32

  • Status changed: Accepted

@ramosian-glider
Copy link
Member Author

Revision 217908 fixes this. I've added your program as test case for tsan.

Reported by dvyukov@google.com on 2014-09-16 21:58:36

  • Status changed: Fixed

@ramosian-glider
Copy link
Member Author

Thanks. I've rebuild libtsan.so from today's compiler-rt and confirm that the test program
now works (with my gcc-4.9).

Please note that the same approach should be taken wrt setcontext()/getcontext() when/if
they are intercepted.
Also please find minor patch to correct reference to this issue from the test.

Thanks again,
Kirill

Reported by kirill.smelkov on 2014-09-17 08:40:32


- _Attachment: [tsan-siglongjmp-fix-issueref.patch](https://storage.googleapis.com/google-code-attachments/thread-sanitizer/issue-75/comment-3/tsan-siglongjmp-fix-issueref.patch)_

@ramosian-glider
Copy link
Member Author

Issue id is fixed in rev 217992.
setcontext()/getcontext can be messy to support, I would prefer to delay it until there
is a real need.

Reported by dvyukov@google.com on 2014-09-17 23:08:27

@ramosian-glider
Copy link
Member Author

Thanks.
I agree about setcontext() support.

Reported by kirill.smelkov on 2014-09-18 07:40:39

@ramosian-glider
Copy link
Member Author

Adding Project:ThreadSanitizer as part of GitHub migration.

Reported by glider@google.com on 2015-07-30 09:21:32

  • Labels added: ProjectThreadSanitizer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant