Description of problem: pthread instructions in giac gives a crash with fedora-rawhide-i386 but not with fedora-27-i386 and not with fedora-rawhide-x86_64 Version-Release number of selected component (if applicable): glibc-2.26.9000 giac-1.4.9.43 (but also earlier version of giac) How reproducible: any giac version on i386 with rawhide Steps to Reproduce: 1.launch icas 2.enter any value, ex: 7 3.it crashes Actual results: Expected results: Additional info: Starting program: /usr/bin/icas [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/libthread_db.so.1". Missing separate debuginfo for /lib/sse2/libgf2x.so.1 Try: dnf --enablerepo='*debug*' install /usr/lib/debug/.build-id/77/abebab3e666aa911fcbfe609cbe9d4cf876a75.debug // Using locale /usr/share/locale/ // fr_FR.UTF-8 // /usr/share/locale/ // giac // UTF-8 // Maximum number of parallel threads 4 Help file /usr/share/giac/doc/fr/aide_cas not found Added 165 synonyms Welcome to giac readline interface (c) 2001,2017 B. Parisse & others Homepage http://www-fourier.ujf-grenoble.fr/~parisse/giac.html Released under the GPL license 3.0 or above See http://www.gnu.org for license details May contain BSD licensed software parts (lapack, atlas, tinymt) ------------------------------------------------- Press CTRL and D simultaneously to finish session Type ?commandname for help 0>> 7 [New Thread 0xf4d73b40 (LWP 38)] Thread 2 "icas" received signal SIGSEGV, Segmentation fault. [Switching to Thread 0xf4d73b40 (LWP 38)] 0x56878f90 in ?? () (gdb) bt #0 0x56878f90 in ?? () #1 0xf6c443c9 in start_thread (arg=0xf4d73b40) at pthread_create.c:463 #2 0xf68337a6 in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:108 adding a break in pthread_exit gives: 0>> 7 [New Thread 0xf4d73b40 (LWP 40)] [Switching to Thread 0xf4d73b40 (LWP 40)] Thread 2 "icas" hit Breakpoint 1, __pthread_exit (value=value@entry=0x0) at pthread_exit.c:25 25 { (gdb) n 26 THREAD_SETMEM (THREAD_SELF, result, value); (gdb) 28 __do_cancel (); (gdb) 0xf78c32c5 in std::imvector<giac::gen>::begin (this=<optimized out>) at vector.h:205 205 iterator begin(){ return _taille>0?_begin_immediate_vect:((_Tp *) _tab); } (gdb) giac::in_thread_eval (arg=0x56722610) at global.cc:3544 3544 gen g = (*v)[0]; (gdb) Thread 2 "icas" received signal SIGSEGV, Segmentation fault. 0x56878f90 in ?? ()
The crash seems to be happening in a destructor during unwinding: 0xf6906ce6 in _Unwind_ForcedUnwind (exc=<optimized out>, stop=<optimized out>, stop_argument=<optimized out>) at ../../../libgcc/unwind.inc:212 212 } 0xf6906ce8 212 } 0xf78c62c5 in std::imvector<giac::gen>::begin (this=<optimized out>) at vector.h:205 205 vector.h: No such file or directory. giac::in_thread_eval (arg=0x56721e10) at global.cc:3544 3544 global.cc: No such file or directory. 0xf78c62ca 3544 in global.cc 0xf78c62cc 3544 in global.cc 0xf78c62cf 3544 in global.cc 0xf71cdf10 in giac::gen::~gen()@plt () from /lib/libgiac.so.0 0x56878790 in ?? () Upon entry into the PLT stub, the value of ebx appears to be invalid: Dump of assembler code for function _ZN4giac3genD1Ev@plt: => 0xf71cdf10 <+0>: jmp *0x15dc(%ebx) 0xf71cdf16 <+6>: push $0x2ba0 0xf71cdf1b <+11>: jmp 0xf71c87c0 (gdb) print/x $ebx $2 = 0xf4d892a0 (gdb) print/x $ebx + 0x15dc $3 = 0xf4d8a87c This does not match the address of the .got: 0xf7fa4fb4 - 0xf7facfec is .got in /lib/libgiac.so.0 In the exception handler landing pad, %ebx is restored from %esi: 0xf78c62c5 <+533>: mov %eax,%edi 0xf78c62c7 <+535>: mov -0x60(%ebp),%eax 0xf78c62ca <+538>: mov %esi,%ebx 0xf78c62cc <+540>: mov %eax,(%esp) 0xf78c62cf <+543>: call 0xf71cdf10 <_ZN4giac3genD1Ev@plt> Upon entry to pthread_exit, both ebx and esi have the correct value: Thread 2 "icas" hit Breakpoint 1, __pthread_exit (value=value@entry=0x0) at pthread_exit.c:25 25 { (gdb) print/x $ebx $1 = 0xf7fa4fb4 (gdb) info symb 0xf7fa4fb4 _GLOBAL_OFFSET_TABLE_ in section .got of /lib/libgiac.so.0 (gdb) print/x $esi $2 = 0xf7fa4fb4 This means that either the exception handling information is faulty or not correctly processed by the libgcc unwinder, or glibc incorrectly clobbers register contents.
Does not reproduce with glibc-2.26.9000-27.fc28.i686.
Seems to be caused by -fstack-clash-protection. Yuck.
Looks like __pthread_unwind is miscompiled. Compiling nptl/unwind.c with -fno-stack-clash-protection fixes this. (gdb) disassemble __pthread_unwind Dump of assembler code for function __pthread_unwind: 0xf6879790 <+0>: push %esi 0xf6879791 <+1>: push %ebx 0xf6879792 <+2>: push %esi 0xf6879793 <+3>: pop %esi 0xf6879794 <+4>: call 0xf68712dd <__x86.get_pc_thunk.dx> 0xf6879799 <+9>: add $0x71867,%edx 0xf687979f <+15>: sub $0x4,%esp 0xf68797a2 <+18>: mov %eax,%esi 0xf68797a4 <+20>: mov 0x38f4(%edx),%eax 0xf68797aa <+26>: test %eax,%eax 0xf68797ac <+28>: jne 0xf68797cd <__pthread_unwind+61> 0xf68797ae <+30>: mov $0x14,%eax 0xf68797b3 <+35>: call *%gs:0x10 0xf68797ba <+42>: mov $0x9,%ecx 0xf68797bf <+47>: mov %eax,%ebx 0xf68797c1 <+49>: mov $0x25,%eax 0xf68797c6 <+54>: call *%gs:0x10 0xf68797cd <+61>: mov 0x38e0(%edx),%edx 0xf68797d3 <+67>: mov %esi,%eax 0xf68797d5 <+69>: ror $0x9,%edx 0xf68797d8 <+72>: xor %gs:0x18,%edx 0xf68797df <+79>: call *%edx End of assembler dump. CFI data: 000000b0 0000002c 000000b4 FDE cie=00000000 pc=00000180..000001d1 DW_CFA_advance_loc: 1 to 00000181 DW_CFA_def_cfa_offset: 8 DW_CFA_offset: r6 (esi) at cfa-8 DW_CFA_advance_loc: 1 to 00000182 DW_CFA_def_cfa_offset: 12 DW_CFA_offset: r3 (ebx) at cfa-12 DW_CFA_advance_loc: 1 to 00000183 DW_CFA_def_cfa_offset: 16 DW_CFA_offset: r6 (esi) at cfa-16 DW_CFA_advance_loc: 1 to 00000184 DW_CFA_restore: r6 (esi) DW_CFA_def_cfa_offset: 12 DW_CFA_advance_loc: 14 to 00000192 DW_CFA_def_cfa_offset: 20 DW_CFA_advance_loc: 51 to 000001c5 DW_CFA_def_cfa_offset: 24 DW_CFA_advance_loc: 1 to 000001c6 DW_CFA_def_cfa_offset: 28 DW_CFA_advance_loc: 1 to 000001c7 DW_CFA_def_cfa_offset: 32 GCC produces this assembly: .globl __GI___pthread_unwind .hidden __GI___pthread_unwind .type __GI___pthread_unwind, @function __GI___pthread_unwind: .LFB55: .loc 1 112 0 .cfi_startproc .LVL27: pushl %esi .cfi_def_cfa_offset 8 .cfi_offset 6, -8 pushl %ebx .cfi_def_cfa_offset 12 .cfi_offset 3, -12 pushl %esi .cfi_def_cfa_offset 16 .cfi_offset 6, -16 popl %esi .cfi_restore 6 .cfi_def_cfa_offset 12 call __x86.get_pc_thunk.bx addl $_GLOBAL_OFFSET_TABLE_, %ebx subl $8, %esp .cfi_def_cfa_offset 20 .loc 1 112 0 movl %eax, %esi .LVL28: .loc 1 118 0 xorl %edx, %edx .LBB21: .loc 1 114 0 #APP # 114 "unwind.c" 1 movl %gs:8,%ecx # 0 "" 2 .LVL29: #NO_APP .LBE21: .loc 1 118 0 xorl %eax, %eax .LVL30: #APP # 118 "unwind.c" 1 movl %eax,%gs:592 movl %edx,%gs:596 # 0 "" 2 .loc 1 119 0 #NO_APP leal unwind_cleanup@GOTOFF(%ebx), %eax #APP # 119 "unwind.c" 1 movl %eax,%gs:600 # 0 "" 2 .loc 1 121 0 #NO_APP leal unwind_stop@GOTOFF(%ebx), %eax addl $592, %ecx .LVL31: pushl %esi .cfi_def_cfa_offset 24 pushl %eax .cfi_def_cfa_offset 28 pushl %ecx .cfi_def_cfa_offset 32 call _Unwind_ForcedUnwind@PLT .LVL32: .loc 1 125 0 call abort@PLT .LVL33: .cfi_endproc .LFE55: .size __GI___pthread_unwind, .-__GI___pthread_unwind .globl __pthread_unwind .set __pthread_unwind,__GI___pthread_unwind I wonder if the push/pop combination of %esi causes the problem because it could obscure the earlier saved value of %esi, so that the unwinder is not able to restore it anymore.
I'm now pretty confident this is a GCC bug. I posted a test case upstream: https://sourceware.org/ml/libc-alpha/2017-12/msg00987.html
Fixed by the rebuild in glibc-2.26.9000-35.fc28.