This is an archive of the discontinued LLVM Phabricator instance.

[sanitizers] Fix internal__exit on Solaris
ClosedPublic

Authored by ro on Sep 28 2020, 4:58 AM.

Details

Summary

TestCases/log-path_test.cpp currently FAILs on Solaris:

$ env ASAN_OPTIONS=log_path=`for((i=0;i<10000;i++)); do echo -n $i; done`  ./log-path_test.cpp.tmp
==5031==ERROR: Path is too long: 01234567...
Segmentation Fault (core dumped)

The SEGV happens here:

Thread 2 received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1 (LWP 1)]
0x00000000 in ?? ()
(gdb) where
#0  0x00000000 in ?? ()
#1  0x080a1e63 in __interceptor__exit (status=1)
    at /vol/gcc/src/llvm/llvm/local/projects/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:3808
#2  0x08135ea8 in __sanitizer::internal__exit (exitcode=1)
    at /vol/gcc/src/llvm/llvm/local/projects/compiler-rt/lib/sanitizer_common/sanitizer_solaris.cc:139
#3  0x0813b105 in __sanitizer::Die ()
    at /vol/gcc/src/llvm/llvm/local/projects/compiler-rt/lib/sanitizer_common/sanitizer_termination.cc:60
#4  0x0812dbc4 in __sanitizer::ReportFile::SetReportPath (
    path=0xfe634000 "01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021"..., 
    this=0x81a3f60 <__sanitizer::report_file>)
    at /vol/gcc/src/llvm/llvm/local/projects/compiler-rt/lib/sanitizer_common/sanitizer_file.cc:80
#5  __sanitizer_set_report_path (
    path=0xfe634000 "01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021"...)
    at /vol/gcc/src/llvm/llvm/local/projects/compiler-rt/lib/sanitizer_common/sanitizer_file.cc:168
#6  0x08120031 in __asan::AsanInitInternal ()
    at /vol/gcc/src/llvm/llvm/local/projects/compiler-rt/lib/asan/asan_rtl.cc:401
#7  0x0814c0d8 in asan.module_ctor ()
#8  0xfe6b05ab in call_array () from /usr/lib/ld.so.1
#9  0xfe6b0776 in call_init () from /usr/lib/ld.so.1
#10 0xfe6b0483 in is_dep_init () from /usr/lib/ld.so.1
#11 0xfe6c03f4 in elf_bndr () from /usr/lib/ld.so.1
#12 0xfe6a1f90 in elf_rtbndr () from /usr/lib/ld.so.1
#13 0xfe6e50a0 in ?? ()
#14 0xfe6b05ab in call_array () from /usr/lib/ld.so.1
#15 0xfe6b0757 in call_init () from /usr/lib/ld.so.1
#16 0xfe6af504 in setup () from /usr/lib/ld.so.1
#17 0xfe6c1ca0 in _setup () from /usr/lib/ld.so.1
#18 0xfe6a1e7f in _rt_boot () from /usr/lib/ld.so.1

when __interceptor__exit tries to call __interception::real__exit which is NULL at this point. This is because the call to __sanitizer_set_report_path above happens before the interceptors are initialized by InitializeAsanInterceptors calling InitializeCommonInterceptors

Ultimately, the problem lies elsewhere, however: internal__exit in sanitizer_solaris.cpp calls _exit itself since there doesn't exit a non-intercepted version in libc. Using the syscall interface isn't usually an option on Solaris because that interface isn't stable and has changed several times. However, in the case of SYS_exit it can be used nontheless: SYS_exit has remained unchanged since at least Solaris 2.5.1 in 1996, and this is what this patch does.

Tested on amd64-pc-solaris2.11.

Diff Detail

Event Timeline

ro created this revision.Sep 28 2020, 4:58 AM
ro requested review of this revision.Sep 28 2020, 4:58 AM
vitalybuka accepted this revision.Sep 30 2020, 4:07 AM

LGTM, but please keep at least git commit description shorter.

This revision is now accepted and ready to land.Sep 30 2020, 4:07 AM
This revision was automatically updated to reflect the committed changes.