Open Quuxplusone opened 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.
(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
> 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.
Attached unwind_01.s
(53488 bytes, text/plain): clang-generated asm
Attached unwind_01-gcc.s
(24676 bytes, text/plain): gcc-generated asm
Related issue/discussion on "that-other-compiler":
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44107
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
Attached PR17505.gcc-s
(6082 bytes, text/plain): gcc-4.0.1 asm of PR17505.cpp
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)
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.
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.
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.
note to self: revisit this AFTER known ABI and DataLayout issues have been resolved
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)