Bug 39291

Summary: _Unwind_Backtrace fails.
Product: gcc Reporter: Pawel Sikora <pawel_sikora>
Component: targetAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED INVALID    
Severity: normal CC: gcc-bugs, ktietz
Priority: P3    
Version: 4.4.0   
Target Milestone: ---   
Host: x86_64-gnu-linux Target: i486-pc-mingw32
Build: x86_64-gnu-linux Known to work:
Known to fail: Last reconfirmed:
Attachments: testcase.
testcase executable built on mingw32
new testcase with binaries.

Description Pawel Sikora 2009-02-24 14:38:05 UTC
Hi,

during porting some software to mingw i've noticed that
unwind_backtrace has some problems. i've tested it with
sjlj and dw2 variant. here're results:

D:\src\mingw-unwind>u-sjlj.exe
foo:enter
bar:enter
zoo:enter
boom!
signalHandler:enter

D:\src\mingw-unwind>u-dw2.exe
foo:enter
bar:enter
zoo:enter
boom!
signalHandler:enter
lookupSymbol: 00401887
lookupSymbol: 0040166A
signalHandler:longjmp


as far i can see both tests got a sigsegv:

Starting program: D:\src\mingw-unwind/u-sjlj.exe
[New thread 2180.0x1c0]
Error: dll starting at 0x77d40000 not found.
Error while mapping shared library sections:
NOT_AN_IMAGE: No such file or directory.
Error while mapping shared library sections:
C:\WINDOWS\SysWOW64\ntdll32.dll: No such file or directory.
Error: dll starting at 0x77d40000 not found.
Error: dll starting at 0x77c20000 not found.
foo:enter
bar:enter
zoo:enter
boom!

Program received signal SIGSEGV, Segmentation fault.
0x0040184f in zoo () at u.c:36
36                      *p = 0;
(gdb) c
Continuing.
signalHandler:enter

Program received signal SIGSEGV, Segmentation fault.
0x00402378 in _Unwind_GetIP ()
(gdb) bt
#0  0x00402378 in _Unwind_GetIP ()
#1  0x004017bc in helper (ctx=0x22fa44, data=0x0) at u.c:14
#2  0x00402b31 in _Unwind_Backtrace ()
#3  0x004017f7 in signalHandler (signalNumber=11) at u.c:24
#4  0x0040166a in _gnu_exception_handler@4 ()
#5  0x00401711 in __mingw_vex ()
#6  0x7d64dbcb in ?? ()
#7  0x0022fad8 in ?? ()
#8  0x0022fb84 in ?? ()
#9  0x0022fb84 in ?? ()
#10 0x003f24f4 in ?? ()
#11 0x0022fb84 in ?? ()
#12 0x0022fbd4 in ?? ()
#13 0x00000000 in ?? ()


Starting program: D:\src\mingw-unwind/u-dw2.exe
[New thread 1308.0x8c8]
Error: dll starting at 0x77d40000 not found.
Error while mapping shared library sections:
NOT_AN_IMAGE: No such file or directory.
Error while mapping shared library sections:
C:\WINDOWS\SysWOW64\ntdll32.dll: No such file or directory.
Error: dll starting at 0x77d40000 not found.
Error: dll starting at 0x77c20000 not found.
foo:enter
bar:enter
zoo:enter
boom!

Program received signal SIGSEGV, Segmentation fault.
0x004018df in zoo () at u.c:36
36                      *p = 0;
(gdb) c
Continuing.
signalHandler:enter
lookupSymbol: 00401887
lookupSymbol: 0040166A
signalHandler:longjmp

Program received signal SIGSEGV, Segmentation fault.
0x00409465 in initialized ()
(gdb) bt
#0  0x00409465 in initialized ()
#1  0x004018a7 in signalHandler (signalNumber=11) at u.c:26
#2  0x0040166a in _gnu_exception_handler@4 ()
#3  0x00401711 in __mingw_vex ()
#4  0x7d64dbcb in ?? ()
#5  0x0022fad8 in ?? ()
#6  0x0022fb84 in ?? ()
#7  0x0022fb84 in ?? ()
#8  0x003f24f4 in ?? ()
#9  0x0022fb84 in ?? ()
#10 0x0022fbd4 in ?? ()
#11 0x00000000 in ?? ()

of course on linux it works perfectly.
testcases were built with 4.4.0-20090220 and latest minw64 crt from svn.
Comment 1 Pawel Sikora 2009-02-24 14:39:56 UTC
Created attachment 17357 [details]
testcase.
Comment 2 Danny Smith 2009-02-25 02:28:50 UTC
I get this with your testcase on mingw32, DW@ build:
GNU C (GCC) version 4.4.0 20090221 (experimental) (mingw32)

gcc -fexceptions -g  u.c

foo:enter
bar:enter
zoo:enter
boom!
signalHandler:enter
lookupSymbol: 00401407
lookupSymbol: 00401232
signalHandler:longjmp
zoo:exit
bar:exit
foo:exit
alive!


Danny
Comment 3 Pawel Sikora 2009-02-25 08:24:54 UTC
(In reply to comment #2)
> I get this with your testcase on mingw32, DW@ build:
> GNU C (GCC) version 4.4.0 20090221 (experimental) (mingw32)

i have a gcc/dw2 configured with:

Using built-in specs.
Target: i486-pc-mingw32
Configured with: ../configure --target=i486-pc-mingw32 --with-arch=i486
--prefix=/local/devel/toolchain44/i486-pc-mingw32.host64
--with-sysroot=/local/devel/toolchain44/i486-pc-mingw32.host64
--libdir=/local/devel/toolchain44/i486-pc-mingw32.host64/lib
--libexecdir=/local/devel/toolchain44/i486-pc-mingw32.host64/lib
--with-slibdir=/local/devel/toolchain44/i486-pc-mingw32.host64/lib
--with-gmp-include=/home/pawels/toolchain/trunk/gcc-math-runtime/include
--with-gmp-lib=/home/pawels/toolchain/trunk/gcc-math-runtime/lib
--with-mpfr-include=/home/pawels/toolchain/trunk/gcc-math-runtime/include
--with-mpfr-lib=/home/pawels/toolchain/trunk/gcc-math-runtime/lib
--disable-multilib --disable-nls --disable-libgomp --disable-libmudflap
--disable-libssp --disable-libstdcxx-pch --with-pic --enable-c99
--enable-long-long --disable-win32-registry --enable-threads=win32
--disable-sjlj-exceptions --enable-shared --enable-__cxa_atexit
--enable-languages=c,c++ --disable-symvers --with-pic --with-long-double-128
--disable-cld --disable-bootstrap
Thread model: win32
gcc version 4.4.0 20090220 (experimental) (GCC)

> gcc -fexceptions -g  u.c
> 
> foo:enter
> bar:enter
> zoo:enter
> boom!
> signalHandler:enter
> lookupSymbol: 00401407
> lookupSymbol: 00401232
> signalHandler:longjmp
> zoo:exit
> bar:exit
> foo:exit
> alive!

could you attach a precompiled .exe? i'll check it on my winxp64.
Comment 4 Danny Smith 2009-02-28 02:38:24 UTC
Created attachment 17376 [details]
testcase executable built on mingw32

testcase executable built on mingw32 attached
Comment 5 Pawel Sikora 2009-02-28 10:43:48 UTC
(In reply to comment #4)
> Created an attachment (id=17376) [edit]
> testcase executable built on mingw32 
> 
> testcase executable built on mingw32 attached

yours u.exe works, but yours u.exe has differents size:

118 167 u-dw2.exe
115 557 u.exe

u-dw2.exe:     file format pei-i386
Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         000054c4  00401000  00401000  00000400  2**4                
                  CONTENTS, ALLOC, LOAD, READONLY, CODE, DATA                 
  1 .data         00000030  00407000  00407000  00005a00  2**2                
                  CONTENTS, ALLOC, LOAD, DATA                                 
  2 .rdata        00000c28  00408000  00408000  00005c00  2**2                
                  CONTENTS, ALLOC, LOAD, READONLY, DATA                       
  3 .bss          00000538  00409000  00409000  00000000  2**5                
                  ALLOC                                                       
  4 .idata        00000558  0040a000  0040a000  00006a00  2**2                
                  CONTENTS, ALLOC, LOAD, DATA                                 
  5 .CRT          00000034  0040b000  0040b000  00007000  2**2                
                  CONTENTS, ALLOC, LOAD, DATA                                 
  6 .tls          00000008  0040c000  0040c000  00007200  2**2                
                  CONTENTS, ALLOC, LOAD, DATA                                 
(...debug sections...)

u.exe:     file format pei-i386
Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         000042f4  00401000  00401000  00000400  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE, DATA
  1 .data         00000020  00406000  00406000  00004800  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .rdata        00000d30  00407000  00407000  00004a00  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .bss          000000c8  00408000  00408000  00000000  2**3
                  ALLOC
  4 .idata        00000374  00409000  00409000  00005800  2**2
                  CONTENTS, ALLOC, LOAD, DATA
(...debug sections...)

as you can see my u-dw2.exe has more sections, so i assume
that we're using different win32 crt. i'm using mingw-w64/svn
compiled with i486-pc-mingw-gcc (solution proposed by K.Tietz).
Comment 6 Pawel Sikora 2009-03-16 21:24:20 UTC
i've tested u-dw2.exe on wine and got more info.

$ ./u-dw2.exe
err:process:start_wineboot failed to start wineboot, err 2
err:process:__wine_kernel_init boot event wait timed out
fixme:msvcrt:__lconv_init  stub
foo:enter
bar:enter
zoo:enter
boom!
signalHandler:enter
lookupSymbol: 00401887
lookupSymbol: 0040166A
signalHandler:longjmp
err:seh:raise_exception Unhandled exception code c0000096 flags 0 addr 0x409461

$ i486-pc-mingw32-objdump -hw u-dw2.exe

u-dw2.exe:     file format pei-i386

Sections:
Idx Name          Size      VMA               LMA               File off  Algn  Flags
  0 .text         000054c4  00401000  00401000  00000400  2**4  CONTENTS, ALLOC, LOAD, READONLY, CODE, DATA
  1 .data         00000030  00407000  00407000  00005a00  2**2  CONTENTS, ALLOC, LOAD, DATA
  2 .rdata        00000c28  00408000  00408000  00005c00  2**2  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .bss          00000538  00409000  00409000  00000000  2**5  ALLOC
  4 .idata        00000558  0040a000  0040a000  00006a00  2**2  CONTENTS, ALLOC, LOAD, DATA
  5 .CRT          00000034  0040b000  0040b000  00007000  2**2  CONTENTS, ALLOC, LOAD, DATA
  6 .tls          00000008  0040c000  0040c000  00007200  2**2  CONTENTS, ALLOC, LOAD, DATA

the 0xc0000096 code means 'EXCEPTION_PRIV_INSTRUCTION'
and the 0x409461 points to the .bss section.
Comment 7 Pawel Sikora 2009-03-22 12:16:56 UTC
haa! i've found the core problem.
on my winxp64 i have DEP (data execution prevention) turned on
for all programs and this is why the testcase (longjmp?) fails.
this looks weird beacuse longjmp on x86-64 with NX-bit enabled
works fine.
Comment 8 Pawel Sikora 2009-03-22 15:44:30 UTC
(In reply to comment #7)
> haa! i've found the core problem.
> on my winxp64 i have DEP (data execution prevention) turned on
> for all programs and this is why the testcase (longjmp?) fails.
> this looks weird beacuse longjmp on x86-64 with NX-bit enabled
> works fine.

please ignore this comment, i've just ran wrong .exe after
changing DEP settings :) but i've found new details
with testcase reduced to setjmp/longjmp comparing gcc-4.4.0
and gcc-4.3.3(tdm-dragon-build).

D:\src\mingw-unwind>u-433-dw2-tdm-dragon.exe
longjmp
alive!

D:\src\mingw-unwind>u-440-dw2.exe
longjmp


Program received signal SIGSEGV, Segmentation fault.
0x00405460 in fctMsvcrtLongJmp ()
(gdb) bt
#0  0x00405460 in fctMsvcrtLongJmp ()
#1  0x004017ae in main () at u.c:12
(gdb) disassemble
Dump of assembler code for function fctMsvcrtLongJmp:
0x00405460 <fctMsvcrtLongJmp+0>:        sbb    %bh,-0x44(%esi)
0x00405463 <fctMsvcrtLongJmp+3>:        ja     0x405466 <initialized+2>

the u-440-dw2.exe doesn't import longjmp symbol from msvcrt.dll
while u-433-dw2-tdm-dragon.exe imports longjmp and _setjmp.


Kai, could you check mingw-w64-crt?
Comment 9 Pawel Sikora 2009-03-22 15:45:46 UTC
Created attachment 17514 [details]
new testcase with binaries.
Comment 10 Pawel Sikora 2009-03-22 21:17:36 UTC
finally, not a gcc bug.

the mingw-w64-crt/misc/mingw_getsp.S has bugs:
- it forces .code64 even for 32-bit mode.
- it jumps directly into data segement -> jmp (_fctMsvcrtLongJmp)

i've tested following patch:

@@ -3,8 +3,6 @@
  * This file is part of the w64 mingw-runtime package.
  * No warranty is given; refer to the file DISCLAIMER within this package.
  */
-       .file   "ceill.S"
-       .code64
        .text
        .align 4
 .globl _mingw_getsp
@@ -26,5 +24,5 @@
   leaq _fctMsvcrtLongJmp(%rip), %rax
   jmpq *(%rax)
 #else
-  jmp (_fctMsvcrtLongJmp)
+  jmp *(_fctMsvcrtLongJmp)
 #endif

but it crashes later in msvcrt.dll:

Breakpoint 1, 0x004023a5 in longjmp ()
(gdb) disassemble
Dump of assembler code for function longjmp:
0x004023a5 <longjmp+0>: jmp    *0x405460
0x004023ab <longjmp+6>: nop

(gdb) disassemble *0x405460
Dump of assembler code for function msvcrt!longjmp:
0x77bc7e18 <msvcrt!longjmp+0>:  mov    0x4(%esp),%ebx
0x77bc7e1c <msvcrt!longjmp+4>:  mov    (%ebx),%ebp
0x77bc7e1e <msvcrt!longjmp+6>:  mov    0x18(%ebx),%esi
(...)

(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x77bc6481 in msvcrt!_local_unwind2 () from C:\WINDOWS\syswow64\msvcrt.dll
(gdb) disassemble
Dump of assembler code for function msvcrt!_local_unwind2:
0x77bc645f <msvcrt!_local_unwind2+0>:   push   %ebx
0x77bc6460 <msvcrt!_local_unwind2+1>:   push   %esi
0x77bc6461 <msvcrt!_local_unwind2+2>:   push   %edi
0x77bc6462 <msvcrt!_local_unwind2+3>:   mov    0x10(%esp),%eax
0x77bc6466 <msvcrt!_local_unwind2+7>:   push   %ebp
0x77bc6467 <msvcrt!_local_unwind2+8>:   push   %eax
0x77bc6468 <msvcrt!_local_unwind2+9>:   push   $0xfffffffe
0x77bc646a <msvcrt!_local_unwind2+11>:  push   $0x77bc6424
0x77bc646f <msvcrt!_local_unwind2+16>:  pushl  %fs:0x0
0x77bc6476 <msvcrt!_local_unwind2+23>:  mov    %esp,%fs:0x0
0x77bc647d <msvcrt!_local_unwind2+30>:  mov    0x24(%esp),%eax
0x77bc6481 <msvcrt!_local_unwind2+34>:  mov    0x8(%eax),%ebx
0x77bc6484 <msvcrt!_local_unwind2+37>:  mov    0xc(%eax),%esi
0x77bc6487 <msvcrt!_local_unwind2+40>:  cmp    $0xffffffff,%esi
0x77bc648a <msvcrt!_local_unwind2+43>:  je     0x77bc64c1 <msvcrt!_local_unwind2+98>
0x77bc648c <msvcrt!_local_unwind2+45>:  cmpl   $0xffffffff,0x28(%esp)
0x77bc6491 <msvcrt!_local_unwind2+50>:  je     0x77bc6499 <msvcrt!_local_unwind2+58>
0x77bc6493 <msvcrt!_local_unwind2+52>:  cmp    0x28(%esp),%esi
0x77bc6497 <msvcrt!_local_unwind2+56>:  jbe    0x77bc64c1 <msvcrt!_local_unwind2+98>
0x77bc6499 <msvcrt!_local_unwind2+58>:  lea    (%esi,%esi,2),%esi
0x77bc649c <msvcrt!_local_unwind2+61>:  mov    (%ebx,%esi,4),%ecx
0x77bc649f <msvcrt!_local_unwind2+64>:  mov    %ecx,0x8(%esp)
0x77bc64a3 <msvcrt!_local_unwind2+68>:  mov    %ecx,0xc(%eax)
0x77bc64a6 <msvcrt!_local_unwind2+71>:  cmpl   $0x0,0x4(%ebx,%esi,4)
0x77bc64ab <msvcrt!_local_unwind2+76>:  jne    0x77bc64bf <msvcrt!_local_unwind2+96>
0x77bc64ad <msvcrt!_local_unwind2+78>:  push   $0x101
0x77bc64b2 <msvcrt!_local_unwind2+83>:  mov    0x8(%ebx,%esi,4),%eax
0x77bc64b6 <msvcrt!_local_unwind2+87>:  call   0x77bc64fb <msvcrt!_abnormal_termination+44>
0x77bc64bb <msvcrt!_local_unwind2+92>:  call   *0x8(%ebx,%esi,4)
0x77bc64bf <msvcrt!_local_unwind2+96>:  jmp    0x77bc647d <msvcrt!_local_unwind2+30>
0x77bc64c1 <msvcrt!_local_unwind2+98>:  popl   %fs:0x0
0x77bc64c8 <msvcrt!_local_unwind2+105>: add    $0x10,%esp
0x77bc64cb <msvcrt!_local_unwind2+108>: pop    %edi
0x77bc64cc <msvcrt!_local_unwind2+109>: pop    %esi
0x77bc64cd <msvcrt!_local_unwind2+110>: pop    %ebx
0x77bc64ce <msvcrt!_local_unwind2+111>: ret