Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

libcxxabi tests all failing on powerpc-darwin8, suspect unwind info incompatibility #17504

Open Quuxplusone opened 11 years ago

Quuxplusone commented 11 years ago
Bugzilla Link PR17505
Status NEW
Importance P normal
Reported by David Fang (fang@csl.cornell.edu)
Reported on 2013-10-07 20:35:01 -0700
Last modified on 2014-02-25 20:08:19 -0800
Version trunk
Hardware Macintosh MacOS X
CC grosbach@apple.com, iains-llvm@btconnect.com, kledzik@apple.com, llvm-bugs@lists.llvm.org
Fixed by commit(s)
Attachments unwind_01.s (53488 bytes, text/plain)
unwind_01-gcc.s (24676 bytes, text/plain)
PR17505.s (8569 bytes, text/plain)
PR17505.gcc-s (6082 bytes, text/plain)
Blocks
Blocked by
See also PR17513
This bug is for tracking the long-standing issue of all libcxxabi tests failing
(Abort trap) on powerpc-darwin8 (latent, not recent).

Theory: suspect that unwind info emitted by CodeGen is not compatible with the
libunwind that ships with /usr/bin/libgcc_s.

I'm probably going to need some help digging through eh-frame dumps to figure
out what's wrong.

First example is unwind_01.cpp.
I'm using the clang++ from a stage1 build of the powerpc-darwin8 branch, which
tracks master.
I build all test executables with -O0 -no-integrated-as.

The clang-built unwind_01 executable gives the following dwarfdump (--eh-frame):
=========== *PASTE* ============
Exception handling frame information for section __eh_frame

0x00000000: CIE
        length: 0x00000018
        CIE_id: 0xffffffff
       version: 0x01
  augmentation: "zPLR"
    code_align: 1
    data_align: -4
   ra_register: 0x41
  Initial Inst: DW_CFA_def_cfa (1, 0)

0x0000001c: FDE
        length: 0x00000030
   CIE_pointer: 0x00000000
    start_addr: 0xfffff28c
    range_size: 0x00000088
  Instructions: DW_CFA_advance_loc4 (16)
                DW_CFA_def_cfa_offset (96)
                DW_CFA_advance_loc4 (0)
                DW_CFA_offset (31, -4)
                DW_CFA_advance_loc4 (0)
                DW_CFA_offset_extended_sf (65, 8)
                DW_CFA_advance_loc4 (4)
                DW_CFA_def_cfa_register (31)
                DW_CFA_nop
                DW_CFA_nop

0x00000050: CIE
        length: 0x00000010
        CIE_id: 0xffffffff
       version: 0x01
  augmentation: "zR"
    code_align: 1
    data_align: -4
   ra_register: 0x41
  Initial Inst: DW_CFA_def_cfa (1, 0)

0x00000064: FDE
        length: 0x0000002c
   CIE_pointer: 0x00000050
    start_addr: 0xfffff674
    range_size: 0x0000003c
  Instructions: DW_CFA_advance_loc4 (16)
                DW_CFA_def_cfa_offset (80)
                DW_CFA_advance_loc4 (0)
                DW_CFA_offset (31, -4)
                DW_CFA_advance_loc4 (0)
                DW_CFA_offset_extended_sf (65, 8)
                DW_CFA_advance_loc4 (4)
                DW_CFA_def_cfa_register (31)
                DW_CFA_nop
                DW_CFA_nop

0x00000094: FDE
        length: 0x0000002c
   CIE_pointer: 0x00000050
    start_addr: 0xfffff684
    range_size: 0x0000003c
  Instructions: DW_CFA_advance_loc4 (16)
                DW_CFA_def_cfa_offset (80)
                DW_CFA_advance_loc4 (0)
                DW_CFA_offset (31, -4)
                DW_CFA_advance_loc4 (0)
                DW_CFA_offset_extended_sf (65, 8)
                DW_CFA_advance_loc4 (4)
                DW_CFA_def_cfa_register (31)
                DW_CFA_nop
                DW_CFA_nop

0x000000c4: FDE
        length: 0x00000030
   CIE_pointer: 0x00000000
    start_addr: 0xfffff274
    range_size: 0x00000094
  Instructions: DW_CFA_advance_loc4 (16)
                DW_CFA_def_cfa_offset (96)
                DW_CFA_advance_loc4 (0)
                DW_CFA_offset (31, -4)
                DW_CFA_advance_loc4 (0)
                DW_CFA_offset_extended_sf (65, 8)
                DW_CFA_advance_loc4 (4)
                DW_CFA_def_cfa_register (31)
                DW_CFA_nop
                DW_CFA_nop

0x000000f8: FDE
        length: 0x0000002c
   CIE_pointer: 0x00000050
    start_addr: 0xfffff6e0
    range_size: 0x0000003c
  Instructions: DW_CFA_advance_loc4 (16)
                DW_CFA_def_cfa_offset (80)
                DW_CFA_advance_loc4 (0)
                DW_CFA_offset (31, -4)
                DW_CFA_advance_loc4 (0)
                DW_CFA_offset_extended_sf (65, 8)
                DW_CFA_advance_loc4 (4)
                DW_CFA_def_cfa_register (31)
                DW_CFA_nop
                DW_CFA_nop

0x00000128: FDE
        length: 0x00000030
   CIE_pointer: 0x00000000
    start_addr: 0xfffff2b0
    range_size: 0x000002f8
  Instructions: DW_CFA_advance_loc4 (16)
                DW_CFA_def_cfa_offset (128)
                DW_CFA_advance_loc4 (0)
                DW_CFA_offset (31, -4)
                DW_CFA_advance_loc4 (0)
                DW_CFA_offset_extended_sf (65, 8)
                DW_CFA_advance_loc4 (4)
                DW_CFA_def_cfa_register (31)
                DW_CFA_nop

0x0000015c: FDE
        length: 0x00000014
   CIE_pointer: 0x00000000
    start_addr: 0xfffff72c
    range_size: 0x00000098
  Instructions: DW_CFA_nop
                DW_CFA_nop
                DW_CFA_nop

0x00000174: FDE
        length: 0x00000014
   CIE_pointer: 0x00000000
    start_addr: 0xfffff7f4
    range_size: 0x00000098
  Instructions: DW_CFA_nop
                DW_CFA_nop
                DW_CFA_nop

0x0000018c: FDE
        length: 0x00000014
   CIE_pointer: 0x00000000
    start_addr: 0xfffff87c
    range_size: 0x00000098
  Instructions: DW_CFA_nop
                DW_CFA_nop
                DW_CFA_nop
=========== end *PASTE* ============

For comparison, I then build unwind_01-copy with g++ (system gcc 4.0.1, no
options), whose executable gives the following dwarfdump --eh-frame:

=========== *PASTE* ============
Exception handling frame information for section __eh_frame

0x00000000: CIE
        length: 0x00000018
        CIE_id: 0xffffffff
       version: 0x01
  augmentation: "zPLR"
    code_align: 1
    data_align: -4
   ra_register: 0x41
  Initial Inst: DW_CFA_def_cfa (1, 0)

0x0000001c: FDE
        length: 0x00000024
   CIE_pointer: 0x00000000
    start_addr: 0xfffffd00
    range_size: 0x0000005c
  Instructions: DW_CFA_advance_loc4 (8)
                DW_CFA_def_cfa_offset (48)
                DW_CFA_offset (31, -4)
                DW_CFA_offset (30, -8)
                DW_CFA_advance_loc4 (4)
                DW_CFA_def_cfa_register (30)
                DW_CFA_nop

0x00000044: FDE
        length: 0x00000028
   CIE_pointer: 0x00000000
    start_addr: 0xfffffd34
    range_size: 0x00000098
  Instructions: DW_CFA_advance_loc4 (16)
                DW_CFA_def_cfa_offset (80)
                DW_CFA_offset (31, -4)
                DW_CFA_offset (30, -8)
                DW_CFA_offset_extended_sf (65, 8)
                DW_CFA_advance_loc4 (4)
                DW_CFA_def_cfa_register (30)
                DW_CFA_nop
                DW_CFA_nop

0x00000070: FDE
        length: 0x00000024
   CIE_pointer: 0x00000000
    start_addr: 0xfffffda0
    range_size: 0x0000005c
  Instructions: DW_CFA_advance_loc4 (8)
                DW_CFA_def_cfa_offset (48)
                DW_CFA_offset (31, -4)
                DW_CFA_offset (30, -8)
                DW_CFA_advance_loc4 (4)
                DW_CFA_def_cfa_register (30)
                DW_CFA_nop

0x00000098: FDE
        length: 0x00000028
   CIE_pointer: 0x00000000
    start_addr: 0xfffffdd4
    range_size: 0x00000098
  Instructions: DW_CFA_advance_loc4 (16)
                DW_CFA_def_cfa_offset (80)
                DW_CFA_offset (31, -4)
                DW_CFA_offset (30, -8)
                DW_CFA_offset_extended_sf (65, 8)
                DW_CFA_advance_loc4 (4)
                DW_CFA_def_cfa_register (30)
                DW_CFA_nop
                DW_CFA_nop

0x000000c4: FDE
        length: 0x00000024
   CIE_pointer: 0x00000000
    start_addr: 0xfffffe40
    range_size: 0x0000005c
  Instructions: DW_CFA_advance_loc4 (8)
                DW_CFA_def_cfa_offset (48)
                DW_CFA_offset (31, -4)
                DW_CFA_offset (30, -8)
                DW_CFA_advance_loc4 (4)
                DW_CFA_def_cfa_register (30)
                DW_CFA_nop

0x000000ec: FDE
        length: 0x00000028
   CIE_pointer: 0x00000000
    start_addr: 0xfffffe74
    range_size: 0x00000098
  Instructions: DW_CFA_advance_loc4 (16)
                DW_CFA_def_cfa_offset (80)
                DW_CFA_offset (31, -4)
                DW_CFA_offset (30, -8)
                DW_CFA_offset_extended_sf (65, 8)
                DW_CFA_advance_loc4 (4)
                DW_CFA_def_cfa_register (30)
                DW_CFA_nop
                DW_CFA_nop

0x00000118: FDE
        length: 0x00000028
   CIE_pointer: 0x00000000
    start_addr: 0xfffff340
    range_size: 0x00000090
  Instructions: DW_CFA_advance_loc4 (16)
                DW_CFA_def_cfa_offset (96)
                DW_CFA_offset (31, -4)
                DW_CFA_offset (30, -8)
                DW_CFA_offset (29, -12)
                DW_CFA_offset_extended_sf (65, 8)
                DW_CFA_advance_loc4 (4)
                DW_CFA_def_cfa_register (30)

0x00000144: FDE
        length: 0x00000028
   CIE_pointer: 0x00000000
    start_addr: 0xfffff3a4
    range_size: 0x000000ac
  Instructions: DW_CFA_advance_loc4 (16)
                DW_CFA_def_cfa_offset (96)
                DW_CFA_offset (31, -4)
                DW_CFA_offset (30, -8)
                DW_CFA_offset (29, -12)
                DW_CFA_offset_extended_sf (65, 8)
                DW_CFA_advance_loc4 (4)
                DW_CFA_def_cfa_register (30)

0x00000170: FDE
        length: 0x00000028
   CIE_pointer: 0x00000000
    start_addr: 0xfffff424
    range_size: 0x000002b4
  Instructions: DW_CFA_advance_loc4 (16)
                DW_CFA_def_cfa_offset (96)
                DW_CFA_offset (31, -4)
                DW_CFA_offset (30, -8)
                DW_CFA_offset (29, -12)
                DW_CFA_offset_extended_sf (65, 8)
                DW_CFA_advance_loc4 (4)
                DW_CFA_def_cfa_register (30)
=========== end *PASTE* ============

In summary, they are quite different.  I just don't know how different they can
be, and still be functional/compatible.
Any hints on how to debug further?
Quuxplusone commented 11 years ago

Does clang and g++ use the same .cfi directive syntax? If so, you can try compiling the test case to a .s file using both compilers, then switch and use the other assembler for each. That can isolate if the problem is that the wrong .cfi directives are being generated by the compiler, or if the assembler is misinterpreting the .cfi directives.

Quuxplusone commented 11 years ago
(In reply to comment #1)
> Does clang and g++ use the same .cfi directive syntax?  If so, you can try
> compiling the test case to a .s file using both compilers, then switch and
> use the other assembler for each.  That can isolate if the problem is that
> the wrong .cfi directives are being generated by the compiler, or if the
> assembler is misinterpreting the .cfi directives.

The system assembler /usr/bin/as (ppc) on darwin8 doesn't support cfi
directives, I usually tell llvm-mc to -disable-cfi.
(In my cctools-2009 source code, I only see reference to cfi under x86.)

Also, I can't directly use the clang integrated assembler for PPC because it
only accepts GNU asm syntax (like 0 instead of r0 for register operands, see PR
16701).  Although, with some sed-tricks, I could hack it into the other
syntax...

However, here's what I found:

clang-built unwind_01:
% env DYLD_LIBRARY_PATH=../lib ./unwind_01
Abort

clang-generated-to-system-assembled unwind_01:
% as unwind_01.s -o unwind_01-cross.o
% ../../gcc40-cmake-build/bin/clang++ unwind_01-cross.o -o unwind_01-cross
% env DYLD_LIBRARY_PATH=../lib ./unwind_01-cross
terminate called after throwing an instance of 'int'
Abort
Quuxplusone commented 11 years ago
> clang-built unwind_01:
> % env DYLD_LIBRARY_PATH=../lib ./unwind_01
> Abort
>
> clang-generated-to-system-assembled unwind_01:
> % as unwind_01.s -o unwind_01-cross.o
> % ../../gcc40-cmake-build/bin/clang++ unwind_01-cross.o -o unwind_01-cross
> % env DYLD_LIBRARY_PATH=../lib ./unwind_01-cross
> terminate called after throwing an instance of 'int'
> Abort

Also, since I'm clang-building with -no-integrated-as, the unwind_01.o and
unwind_01-cross.o objects are identical (duh).
The problem can't be with the system assembler.
clang vs. gcc produce different __eh_frame asm, as shown by dwarfdump.
I'll attach the .s in a moment.
Quuxplusone commented 11 years ago

Attached unwind_01.s (53488 bytes, text/plain): clang-generated asm

Quuxplusone commented 11 years ago

Attached unwind_01-gcc.s (24676 bytes, text/plain): gcc-generated asm

Quuxplusone commented 11 years ago
Related issue/discussion on "that-other-compiler":
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44107
Quuxplusone commented 11 years ago
simple test case "PR17505.cpp":
int main(void) {
        try {
                int i = 5;
                throw i;
        } catch (int) {
                return 0;
        }
        return 1;
}

Attaching asm files and dwarfdumps from gcc-4.0.1 and clang-r194745 in a moment.

% clang++ -std=c++0x -stdlib=libc++ -O0 -no-integrated-as -fverbose-asm -fPIC -
save-temps -c PR17505.cpp -o PR17505.o

% g++ -fno-omit-frame-pointer -save-temps -dA -c PR17505.cpp -o PR17505.gcc-o
Quuxplusone commented 11 years ago

Attached PR17505.s (8569 bytes, text/plain): clang asm of PR17505.cpp

Quuxplusone commented 11 years ago

Attached PR17505.gcc-s (6082 bytes, text/plain): gcc-4.0.1 asm of PR17505.cpp

Quuxplusone commented 11 years ago
eh-frame dwarf dumps of above asm files:

% cat PR17505.dwarfdump

Exception handling frame information for section __eh_frame

0x00000000: CIE
        length: 0x00000018
        CIE_id: 0xffffffff
       version: 0x01
  augmentation: "zPLR"
    code_align: 1
    data_align: -4
   ra_register: 0x41
  Initial Inst: DW_CFA_def_cfa (1, 0)

0x0000001c: FDE
        length: 0x00000030
   CIE_pointer: 0x00000000
    start_addr: 0xfffffe2c
    range_size: 0x000000bc
  Instructions: DW_CFA_advance_loc4 (16)
                DW_CFA_def_cfa_offset (96)
                DW_CFA_advance_loc4 (0)
                DW_CFA_offset (31, -4)
                DW_CFA_advance_loc4 (0)
                DW_CFA_offset_extended_sf (65, 8)
                DW_CFA_advance_loc4 (4)
                DW_CFA_def_cfa_register (31)
                DW_CFA_nop
                DW_CFA_nop

% cat PR17505.gcc-dwarfdump

Exception handling frame information for section __eh_frame

0x00000000: CIE
        length: 0x00000018
        CIE_id: 0xffffffff
       version: 0x01
  augmentation: "zPLR"
    code_align: 1
    data_align: -4
   ra_register: 0x41
  Initial Inst: DW_CFA_def_cfa (1, 0)

0x0000001c: FDE
        length: 0x00000028
   CIE_pointer: 0x00000000
    start_addr: 0xfffffe54
    range_size: 0x000000a8
  Instructions: DW_CFA_advance_loc4 (16)
                DW_CFA_def_cfa_offset (96)
                DW_CFA_offset (31, -4)
                DW_CFA_offset (30, -8)
                DW_CFA_offset (29, -12)
                DW_CFA_offset_extended_sf (65, 8)
                DW_CFA_advance_loc4 (4)
                DW_CFA_def_cfa_register (30)
Quuxplusone commented 11 years ago

Iain and I observed that llvm/clang uses a different register for the frame pointer (r31) than system-gcc does (r30). Perhaps we should tackle that difference first, as that also affects the eh_frame information that is written out.

Quuxplusone commented 10 years ago
Iain posted patches to llvm-commits which address this issue:

http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20131202/197610.html

With the amendments in my reply, I have libc++abi passing ALL-but-two tests!
This is great progress on the powerpc-darwin8 front.
Even if libc++ ends up using libsupc++ over libc++abi, this at least shows the
majority of eh-frame generation is consistent with what the darwin8 system
expects.
Quuxplusone commented 10 years ago
This is *mostly* fixed now, thanks to Iain's r198744.
Also backported to powerpc-darwin8-rel-3.4 branch.

[fangism:LLVM-svn/libcxxabi.git/test] fang% make check
Using TESTS_ENVIROMENT=DYLD_LIBRARY_PATH=../lib
======== catch_array_01
PASS
======== catch_array_02
PASS
======== catch_class_01
PASS
======== catch_class_02
PASS
======== catch_class_03
PASS
======== catch_class_04
PASS
======== catch_const_pointer_nullptr
PASS
======== catch_function_01
PASS
======== catch_function_02
PASS
======== catch_member_data_pointer_01
PASS
======== catch_member_function_pointer_01
PASS
======== catch_member_pointer_nullptr
PASS
======== catch_pointer_nullptr
PASS
======== catch_ptr
PASS
======== catch_ptr_02
PASS
======== dynamic_cast14
23411.9 microseconds
PASS
======== dynamic_cast3
9302.82 microseconds
PASS
======== dynamic_cast5
6157.12 microseconds
PASS
======== dynamic_cast_stress
106.85 microseconds
PASS
======== test_aux_runtime
PASS
======== test_demangle
FAIL
======== test_exception_storage
PASS
======== test_fallback_malloc
Offset: 0   size: 128 Next: 128
Total Free space: 128
fallback_malloc ( 1024 ) --> 0
Offset: 0   size: 128 Next: 128
Total Free space: 128
fallback_malloc ( 32 ) --> 480
Offset: 0   size: 119 Next: 128
Total Free space: 119
Offset: 0   size: 128 Next: 128
Total Free space: 128

Constant exhaustion tests
Allocated 14 32 byte chunks
Offset: 0   size: 2 Next: 128
Total Free space: 2
Offset: 2   size: 126 Next: 0
  Offset: 0 size: 2 Next: 128
Total Free space: 128
----
Allocated 14 32 byte chunks
Offset: 0   size: 128 Next: 128
Total Free space: 128
----
Allocated 14 32 byte chunks
Offset: 2   size: 126 Next: 0
  Offset: 0 size: 2 Next: 128
Total Free space: 128

Growing exhaustion tests
Allocated 5 { 32, 48, 72, 108, 162 ... }  byte chunks
Offset: 0   size: 17 Next: 128
Total Free space: 17
Offset: 17  size: 111 Next: 0
  Offset: 0 size: 17 Next: 128
Total Free space: 128
----
Offset: 17  size: 111 Next: 0
  Offset: 0 size: 17 Next: 128
Total Free space: 128
Allocated 5 { 32, 48, 72, 108, 162 ... }  byte chunks
Offset: 0   size: 128 Next: 128
Total Free space: 128
----
Allocated 5 { 32, 48, 72, 108, 162 ... }  byte chunks
Offset: 17  size: 111 Next: 0
  Offset: 0 size: 17 Next: 128
Total Free space: 128

Complete exhaustion tests
Allocated 4 chunks
Total Free space: 0
Offset: 0   size: 128 Next: 128
Total Free space: 128
----
Offset: 0   size: 128 Next: 128
Total Free space: 128
Allocated 4 chunks
Offset: 0   size: 128 Next: 128
Total Free space: 128
----
Allocated 4 chunks
Offset: 0   size: 128 Next: 128
Total Free space: 128

PASS
======== test_guard
PASS
======== test_vector1
PASS
======== test_vector2
PASS
======== test_vector3
PASS
======== unwind_01
PASS
======== unwind_02
PASS
======== unwind_03
PASS
======== unwind_04
PASS
======== unwind_05
libc++abi.dylib: terminating with uncaught exception of type int
FAIL
Failures: 2
make: *** [check] Error 1

Not sure what to make of those two failing tests yet.
Also, that patch cures most exception-related test failures in libc++'s test
suite.

I would like to close this after the last two failures are fixed or at least
understood.
Quuxplusone commented 10 years ago

note to self: revisit this AFTER known ABI and DataLayout issues have been resolved