This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/38952] [4.4 Regression] EH does not work.



------- Comment #5 from dave dot korn dot cygwin at gmail dot com  2009-01-24 00:10 -------
  Here is a disassembly of the start of the main function:

(gdb) disass main
Dump of assembler code for function main:
0x00401070 <main+0>:    push   %ebp
0x00401071 <main+1>:    mov    %esp,%ebp
0x00401073 <main+3>:    and    $0xfffffff0,%esp
0x00401076 <main+6>:    sub    $0x60,%esp
0x00401079 <main+9>:    mov    %ebx,0x54(%esp)
0x0040107d <main+13>:   mov    %esi,0x58(%esp)
0x00401081 <main+17>:   mov    %edi,0x5c(%esp)
0x00401085 <main+21>:   movl   $0x407600,0x34(%esp)
0x0040108d <main+29>:   movl   $0x407bd4,0x38(%esp)
0x00401095 <main+37>:   lea    0x3c(%esp),%eax
0x00401099 <main+41>:   lea    0x50(%esp),%edx
0x0040109d <main+45>:   mov    %edx,(%eax)
0x0040109f <main+47>:   movl   $0x4010ec,0x4(%eax)
0x004010a6 <main+54>:   mov    %esp,0x8(%eax)
0x004010a9 <main+57>:   lea    0x1c(%esp),%eax
0x004010ad <main+61>:   mov    %eax,(%esp)
0x004010b0 <main+64>:   call   0x405068 <_Unwind_SjLj_Register>
0x004010b5 <main+69>:   call   0x40515c <__main>
0x004010ba <main+74>:   movl   $0x4,(%esp)
0x004010c1 <main+81>:   call   0x406b00 <__cxa_allocate_exception>
0x004010c6 <main+86>:   movl   $0x1,(%eax)
0x004010cc <main+92>:   movl   $0x0,0x8(%esp)
0x004010d4 <main+100>:  movl   $0x40e7e0,0x4(%esp)
0x004010dc <main+108>:  mov    %eax,(%esp)
0x004010df <main+111>:  movl   $0x1,0x20(%esp)
0x004010e7 <main+119>:  call   0x4075a0 <__cxa_throw>
0x004010ec <main+124>:  mov    0x24(%esp),%eax
0x004010f0 <main+128>:  mov    %eax,(%esp)
0x004010f3 <main+131>:  call   0x406da0 <__cxa_begin_catch>

  If we set a breakpoint on every function call, and run through it:

(gdb) r
Starting program: /win/i/FSF-Gcc/obj-sjlj/gcc/testsuite/g++/eh.exe
[New thread 648.0x754]
[New thread 648.0x31c]

Breakpoint 1, main () at ./eh.C:4
4       {
(gdb) print $esp
$2 = (void *) 0x22ccac
(gdb) c
Continuing.

Breakpoint 3, 0x004010b0 in main () at ./eh.C:4
4       {
(gdb) print $esp
$3 = (void *) 0x22cc40
(gdb) print $ebp
$14 = (void *) 0x22cca8
(gdb) c
Continuing.

Breakpoint 4, main () at ./eh.C:4
4       {
(gdb) print $ebp
$4 = (void *) 0x22cca8
(gdb) c
Continuing.

Breakpoint 5, 0x004010c1 in main () at ./eh.C:6
6           throw 1;
(gdb) print $ebp
$5 = (void *) 0x22cca8
(gdb) c
Continuing.

Breakpoint 6, 0x004010e7 in main () at ./eh.C:6
6           throw 1;
(gdb) print $ebp
$6 = (void *) 0x22cca8
(gdb) c
Continuing.

Breakpoint 10, _Unwind_SjLj_RaiseException (exc=0x100325b8)
    at /gnu/gcc/gcc/libgcc/../gcc/unwind-sjlj.c:148
148       if (use_fc_key < 0)
Current language:  auto; currently c
(gdb) print $ebp
$7 = (void *) 0x22cc18
(gdb) c
Continuing.

Breakpoint 7, 0x004010f3 in main () at ./eh.C:8
8         catch (...) {
Current language:  auto; currently c++
(gdb) print $ebp
$8 = (void *) 0x22cc90
(gdb) c
Continuing.

Breakpoint 8, 0x00401100 in main () at ./eh.C:8
8         catch (...) {
(gdb) print $ebp
$9 = (void *) 0x22cc90
(gdb) c
Continuing.

Breakpoint 9, 0x0040110c in main () at ./eh.C:8
8         catch (...) {
(gdb) print $ebp
$10 = (void *) 0x22cc90
(gdb) c
Continuing.

Breakpoint 11, 0x00401122 in main () at ./eh.C:11
11      }
(gdb) print $ebp
$11 = (void *) 0x22cc90
(gdb) c
Continuing.

Breakpoint 2, 0x00401125 in main () at ./eh.C:11
11      }
(gdb) print $ebp
$12 = (void *) 0x100324fa
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x00000000 in ?? ()
(gdb)

... we can see that $ebp is correct right up until the call to __cxa_throw at
0x004010e7, but when we return to the catch landing site at 0x004010f3, $ebp is
incorrect.

  This incorrect value is calculated in the code at the start of main(), where 
the code generated by sjlj_emit_function_enter calls
expand_builtin_setjmp_setup to initialise the jbuf[] member of the struct
SjLj_Function_Context that it then passes to _Unwind_SjLj_Register.  From that
call:

0x004010a9 <main+57>:   lea    0x1c(%esp),%eax
0x004010ad <main+61>:   mov    %eax,(%esp)
0x004010b0 <main+64>:   call   0x405068 <_Unwind_SjLj_Register>

the struct is at an offset of 0x1c on the stack.  Looking at the memory dump,
just before the call:

0x22cc40:       0x0022cc5c      0xbdbdbdbd      0xbdbdbdbd      0xbdbdbdbd
0x22cc50:       0xbdbdbdbd      0xbdbdbdbd      0xbdbdbdbd      0xbdbdbdbd
0x22cc60:       0xbdbdbdbd      0xbdbdbdbd      0xbdbdbdbd      0xbdbdbdbd
0x22cc70:       0xbdbdbdbd      0x00407600      0x00407bd4      0x0022cc90
0x22cc80:       0x004010ec      0x0022cc40      0xbdbdbdbd      0xbdbdbdbd
0x22cc90:       0xbdbdbdbd      0x00000000      0x611021a0      0x0040546c
0x22cca0:       0xbdbdbdbd      0xbdbdbdbd      0x0022cd98      0x610060e8
0x22ccb0:       0x00000001      0x100324a0      0x10030090      0x60030000

.. shows that the struct has been initialised like so:

OFFS:0x001c:  prev = 0xbdbdbdbd, call_Site 0xbdbdbdbd
OFFS:0x0024:  data[4] = { 0xbdbdbdbd, 0xbdbdbdbd, 0xbdbdbdbd, 0xbdbdbdbd }
OFFS:0x0034:  personality = 0x00407600 = <__gxx_personality_sj0>
OFFS:0x0038:  lsda = 0x00407bd4 = <__DTOR_LIST__+16>:    0x010d00ff
OFFS:0x003c:  jbuf = void*[5] at 
   0x22cc7c:                                                       0x0022cc90
   0x22cc80:       0x004010ec      0x0022cc40      0xbdbdbdbd      0xbdbdbdbd

(note that I manually filled the empty stack frame with 0xbd bytes immediately
after it was allocated in this run).

  A comment in expand_builtin_setjmp_setup says 

  /* We store the frame pointer and the address of receiver_label in
     the buffer and use the rest of it for the stack save area, which
     is machine-dependent.  */

and 0x004010ec is indeed the receiver_label, but 0x0022cc90 is not the frame
pointer.  The code that initialises this struct is

0x00401085 <main+21>:   movl   $0x407600,0x34(%esp)
0x0040108d <main+29>:   movl   $0x407bd4,0x38(%esp)
0x00401095 <main+37>:   lea    0x3c(%esp),%eax
0x00401099 <main+41>:   lea    0x50(%esp),%edx
0x0040109d <main+45>:   mov    %edx,(%eax)
0x0040109f <main+47>:   movl   $0x4010ec,0x4(%eax)
0x004010a6 <main+54>:   mov    %esp,0x8(%eax)

and so it is clear that the "lea 0x50(%esp),%edx" is the source of the
incorrect value 0x0022cc90, that is stored into jbuf[0].

  As this is an offset relative to the stack pointer, yet it originates in the
line

  emit_move_insn (mem, targetm.builtin_setjmp_frame_value ());

I am working on the hypothesis that something has gone wrong with frame pointer
elimination.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38952


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]