https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71370
Bug ID: 71370
Summary: asan infinite recursion if gcc configured without tls
Product: gcc
Version: 5.3.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: sanitizer
Assignee: unassigned at gcc dot gnu.org
Reporter: vladimir.simonov at acronis dot com
CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org,
jakub at gcc dot gnu.org, kcc at gcc dot gnu.org
Target Milestone: ---
Hi,
If gcc configured x86_64 with --disable-tls below code
crashes in runtime with stack overflow.
#include <cstdio>
#include <cstdlib>
namespace
{
class A
{
public:
A() : B(malloc(10))
{
}
~A()
{
free(B);
}
void* B;
};
A C;
}
int main(int argc, char* argv[])
{
printf("Hello world!\n");
return 0;
}
Here is gdb log
Program received signal SIGSEGV, Segmentation fault.
__sanitizer::StackDepotBase<__sanitizer::StackDepotNode, 1, 20>::Put (
this=this@entry=0x9510a0 <__sanitizer::theDepot>, args=...,
inserted=inserted@entry=0x0)
at
../../../../gcc-5.3.0/libsanitizer/sanitizer_common/sanitizer_stackdepotbase.h:95
95
../../../../gcc-5.3.0/libsanitizer/sanitizer_common/sanitizer_stackdepotbase.h:
No such file or directory.
(gdb) up 10000
#10000 0x00000000004ad512 in __emutls_get_address (
obj=obj@entry=0x4dbda0 <__emutls_v._ZN6__lsan15disable_counterE>)
at ../../../gcc-5.3.0/libgcc/emutls.c:159
159 ../../../gcc-5.3.0/libgcc/emutls.c: No such file or directory.
(gdb)
#17245 0x0000000000404d46 in _start ()
(gdb) down
#17244 0x00007ffff751caa5 in __libc_start_main () from /lib64/libc.so.6
(gdb)
#17243 0x00000000004a8ccb in __libc_csu_init ()
(gdb)
#17242 _GLOBAL__sub_I_main.cpp(void) ()
at H:/AB2/linex/dsk_supp/test/asan/main.cpp:26
26 H:/AB2/linex/dsk_supp/test/asan/main.cpp: No such file or directory.
(gdb)
#17241 __static_initialization_and_destruction_0 (__initialize_p=1,
__priority=65535) at H:/AB2/linex/dsk_supp/test/asan/main.cpp:19
19 in H:/AB2/linex/dsk_supp/test/asan/main.cpp
(gdb)
#17240 0x0000000000404cba in (anonymous namespace)::A::A (
this=0x1151d40 <(anonymous namespace)::C>)
at H:/AB2/linex/dsk_supp/test/asan/main.cpp:9
9 in H:/AB2/linex/dsk_supp/test/asan/main.cpp
(gdb)
#17239 0x000000000047b359 in __interceptor_malloc (size=size@entry=10)
at ../../../../gcc-5.3.0/libsanitizer/asan/asan_malloc_linux.cc:39
39 ../../../../gcc-5.3.0/libsanitizer/asan/asan_malloc_linux.cc: No such
file or directory.
(gdb)
#17238 0x000000000040b228 in __asan::asan_malloc (size=size@entry=10,
stack=stack@entry=0x7fffffffdb60)
at ../../../../gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc:595
595 ../../../../gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc: No such
file or directory.
(gdb)
#17237 0x000000000040ab1a in __asan::Allocate (size=<optimized out>,
size@entry=10, alignment=<optimized out>, alignment@entry=8,
stack=stack@entry=0x7fffffffdb60,
alloc_type=alloc_type@entry=__asan::FROM_MALLOC,
can_fill=can_fill@entry=true)
at ../../../../gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc:383
383 in ../../../../gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc
(gdb)
#17236 0x0000000000493db0 in __lsan::DisabledInThisThread ()
at ../../../../gcc-5.3.0/libsanitizer/lsan/lsan_common.cc:33
33 ../../../../gcc-5.3.0/libsanitizer/lsan/lsan_common.cc: No such file or
directory.
(gdb)
#17235 0x00000000004ad512 in __emutls_get_address (
obj=obj@entry=0x4dbda0 <__emutls_v._ZN6__lsan15disable_counterE>)
at ../../../gcc-5.3.0/libgcc/emutls.c:159
159 ../../../gcc-5.3.0/libgcc/emutls.c: No such file or directory.
(gdb)
#17234 0x000000000047b4c6 in __interceptor_calloc (nmemb=nmemb@entry=34,
size=size@entry=8)
at ../../../../gcc-5.3.0/libsanitizer/asan/asan_malloc_linux.cc:55
55 ../../../../gcc-5.3.0/libsanitizer/asan/asan_malloc_linux.cc: No such
file or directory.
(gdb)
#17233 0x000000000040b268 in __asan::asan_calloc (nmemb=nmemb@entry=34,
size=size@entry=8, stack=stack@entry=0x7fffffffd200)
at ../../../../gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc:601
601 ../../../../gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc: No such
file or directory.
(gdb)
#17232 0x000000000040ab1a in __asan::Allocate (size=<optimized out>,
size@entry=272, alignment=<optimized out>, alignment@entry=8,
stack=stack@entry=0x7fffffffd200,
alloc_type=alloc_type@entry=__asan::FROM_MALLOC,
can_fill=can_fill@entry=false)
at ../../../../gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc:383
383 in ../../../../gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc
(gdb)
#17231 0x0000000000493db0 in __lsan::DisabledInThisThread ()
at ../../../../gcc-5.3.0/libsanitizer/lsan/lsan_common.cc:33
33 ../../../../gcc-5.3.0/libsanitizer/lsan/lsan_common.cc: No such file or
directory.
(gdb)
#17230 0x00000000004ad512 in __emutls_get_address (
obj=obj@entry=0x4dbda0 <__emutls_v._ZN6__lsan15disable_counterE>)
at ../../../gcc-5.3.0/libgcc/emutls.c:159
159 ../../../gcc-5.3.0/libgcc/emutls.c: No such file or directory.
(gdb)
#17229 0x000000000047b4c6 in __interceptor_calloc (nmemb=nmemb@entry=34,
size=size@entry=8)
at ../../../../gcc-5.3.0/libsanitizer/asan/asan_malloc_linux.cc:55
55 ../../../../gcc-5.3.0/libsanitizer/asan/asan_malloc_linux.cc: No such
file or directory.
(gdb)
#17228 0x000000000040b268 in __asan::asan_calloc (nmemb=nmemb@entry=34,
size=size@entry=8, stack=stack@entry=0x7fffffffc880)
at ../../../../gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc:601
601 ../../../../gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc: No such
file or directory.
(gdb)
#17227 0x000000000040ab1a in __asan::Allocate (size=<optimized out>,
size@entry=272, alignment=<optimized out>, alignment@entry=8,
stack=stack@entry=0x7fffffffc880,
alloc_type=alloc_type@entry=__asan::FROM_MALLOC,
can_fill=can_fill@entry=false)
at ../../../../gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc:383
383 in ../../../../gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc
(gdb)
#17226 0x0000000000493db0 in __lsan::DisabledInThisThread ()
at ../../../../gcc-5.3.0/libsanitizer/lsan/lsan_common.cc:33
33 ../../../../gcc-5.3.0/libsanitizer/lsan/lsan_common.cc: No such file or
directory.
(gdb)
#17225 0x00000000004ad512 in __emutls_get_address (
obj=obj@entry=0x4dbda0 <__emutls_v._ZN6__lsan15disable_counterE>)
at ../../../gcc-5.3.0/libgcc/emutls.c:159
159 ../../../gcc-5.3.0/libgcc/emutls.c: No such file or directory.
(gdb)
#17224 0x000000000047b4c6 in __interceptor_calloc (nmemb=nmemb@entry=34,
size=size@entry=8)
at ../../../../gcc-5.3.0/libsanitizer/asan/asan_malloc_linux.cc:55
55 ../../../../gcc-5.3.0/libsanitizer/asan/asan_malloc_linux.cc: No such
file or directory.
(gdb)
IMO the problem is in __lsan::DisabledInThisThread call from __asan::Allocate.
Call of DisabledInThisThread "instantiates" thread specific "THREADLOCAL int
disable_counter;". But __emutls_get_address (which is used if gcc configured
without tls) in turn requires memory allocation.
I'd suggested something like
--- gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc 2014-11-13
23:41:38.000000000 +0300
+++ gcc-5.3.0/libsanitizer/asan/asan_allocator2.cc 2016-05-27
16:03:55.616269900 +0300
@@ -379,7 +379,8 @@
REAL(memset)(res, fl.malloc_fill_byte, fill_size);
}
#if CAN_SANITIZE_LEAKS
- m->lsan_tag = __lsan::DisabledInThisThread() ? __lsan::kIgnored
+ if (common_flags()->detect_leaks)
+ m->lsan_tag = __lsan::DisabledInThisThread() ? __lsan::kIgnored
: __lsan::kDirectlyLeaked;
#endif
// Must be the last mutation of metadata in this function.
As minimum if gcc is configured without tls asan will work with detect_leaks=0.
Thank you
Vladimir