bin-x86_64/diet segfaults in findtlsdata()
[email protected] Mon, 6 Aug 2018 13:54:29 +0200 (CEST)
| Newsgroups | gmane.linux.lib.dietlibc |
|---|---|
| Message-ID | <[email protected]> |
Hi,
I'm getting a new segfault while building the current dietlibc cvs:
...
make: Entering directory '/tmp/dietlibc-cvs'
bin-x86_64/diet gcc -D__dietlibc__ -g -O0 -march=native -Wall -fno-stack-protector -std=gnu99 -W -Wall -Wextra -Wchar-subscripts -Wmissing-prototypes -Wmissing-declarations -Wno-switch -Wno-unused -Wredundant-decls -Wshadow -o bin-x86_64/elftrunc contrib/elftrunc.c
make: *** [Makefile:346: bin-x86_64/elftrunc] Segmentation fault
After a bit of gdbugging here is the segfault context:
inside the function findtlsdata(long* auxvec) in lib/stackgap-common.h:
...
static void findtlsdata(long* auxvec) {
#if (__WORDSIZE == 64)
Elf64_Phdr* x=0;
#else
Elf32_Phdr* x=0;
#endif
size_t i,n=0;
while (*auxvec) {
if (auxvec[0]==3) { /* AT_PHDR */
x=(void*)auxvec[1];
if (n) break;
} else if (auxvec[0]==5) { /* AT_PHNUM */
n=auxvec[1];
if (x) break;
}
auxvec+=2;
} /* if we don't find the entry, the kernel let us down */
if (!x || !n) return; /* a kernel this old does not support thread local storage anyway */
for (i=0; i<n; ++i)
if (x[i].p_type==PT_TLS) {
__tdataptr=(void*)x[i].p_vaddr;
__tdatasize=x[i].p_filesz;
__tmemsize=x[i].p_memsz;
if (__tmemsize&15)
__tmemsize=(__tmemsize+15)&~15;
break;
}
/* if there is no PT_TLS section, there is no thread-local data, and
* we just leave the __t* variables zero */
}
...
it searches the auxvec table for the PHDR address and the PHNUM and it actually finds something:
here is a memory dump of the auxvec in gdb:
(gdb) x/40ug auxvec
0x7fffffffe1e8: 33 140737354125312
0x7fffffffe1f8: 16 3219913727
0x7fffffffe208: 6 4096
0x7fffffffe218: 17 100
0x7fffffffe228: 3 4194368
0x7fffffffe238: 4 56
0x7fffffffe248: 5 6
0x7fffffffe258: 7 0
0x7fffffffe268: 8 0
0x7fffffffe278: 9 4198400
0x7fffffffe288: 11 1000
0x7fffffffe298: 12 1000
0x7fffffffe2a8: 13 999
0x7fffffffe2b8: 14 999
0x7fffffffe2c8: 23 0
0x7fffffffe2d8: 25 140737488347945
0x7fffffffe2e8: 26 0
0x7fffffffe2f8: 31 140737488351118
0x7fffffffe308: 15 140737488347961
0x7fffffffe318: 0 0
(gdb) x/40xg auxvec
0x7fffffffe1e8: 0x0000000000000021 0x00007ffff7ffd000
0x7fffffffe1f8: 0x0000000000000010 0x00000000bfebfbff
0x7fffffffe208: 0x0000000000000006 0x0000000000001000
0x7fffffffe218: 0x0000000000000011 0x0000000000000064
0x7fffffffe228: 0x0000000000000003 0x0000000000400040
0x7fffffffe238: 0x0000000000000004 0x0000000000000038
0x7fffffffe248: 0x0000000000000005 0x0000000000000006
0x7fffffffe258: 0x0000000000000007 0x0000000000000000
0x7fffffffe268: 0x0000000000000008 0x0000000000000000
0x7fffffffe278: 0x0000000000000009 0x0000000000401000
0x7fffffffe288: 0x000000000000000b 0x00000000000003e8
0x7fffffffe298: 0x000000000000000c 0x00000000000003e8
0x7fffffffe2a8: 0x000000000000000d 0x00000000000003e7
0x7fffffffe2b8: 0x000000000000000e 0x00000000000003e7
0x7fffffffe2c8: 0x0000000000000017 0x0000000000000000
0x7fffffffe2d8: 0x0000000000000019 0x00007fffffffe329
0x7fffffffe2e8: 0x000000000000001a 0x0000000000000000
0x7fffffffe2f8: 0x000000000000001f 0x00007fffffffef8e
0x7fffffffe308: 0x000000000000000f 0x00007fffffffe339
0x7fffffffe318: 0x0000000000000000 0x0000000000000000
(gdb)
The pointer 'x' gets the value 0x400040 and the program segfaults as soon as 'x'
is dereferenced in:
if (x[i].p_type==PT_TLS) {
with i==0.
Can someone recognize something stange in this ? Is the address 0x400040 'plausible'
or is it obviously wrong.
I'm compiling natively with gcc 8.2 on linux 4.17.11.
giorgio