あなたが解体を見れば、あなたは一般的な保護(GP)例外はSSE movaps
命令で発生していることがわかります。でも呼ばれmy_exception :: my_exception()コンストラクタの前に
a.out`main:
0x100000ad0 : pushq %rbp
0x100000ad1 : movq %rsp, %rbp
0x100000ad4 : subq $0x20, %rsp
0x100000ad8 : movl $0x0, -0x4(%rbp)
0x100000adf : movl $0x10, %eax
0x100000ae4 : movl %eax, %edi
0x100000ae6 : callq 0x100000dea ; symbol stub for: __cxa_allocate_exception
0x100000aeb : movq %rax, %rdi
0x100000aee : xorps %xmm0, %xmm0
-> 0x100000af1 : movaps %xmm0, (%rax)
0x100000af4 : movq %rdi, -0x20(%rbp)
0x100000af8 : movq %rax, %rdi
0x100000afb : callq 0x100000b40 ; my_exception::my_exception
...
movaps
命令は、__cxa_allocate_exception(size_t)によって返されたメモリのブロックをゼロにするために使用されます。しかし、このポインタ(私の場合は0x0000000100103498)は、16バイト境界であることが保証されていません。 movaps
命令のソースオペランドまたはデスティネーションオペランドがメモリオペランドの場合、オペランドは、を16バイト境界に揃えなければなりません。そうしないと、GP例外が生成されます。
問題を一時的に解決する方法の1つは、SSE命令(-mno-sse
)なしでコンパイルすることです。 SSE命令はパフォーマンスを向上させることができるため、理想的なソリューションではありません。
私はこれがhttp://reviews.llvm.org/D18479に関連していると思います:
r246985は、Itaniumが_Unwind_Exceptionが並ぶ「ダブルワード」であるべきと言うと構造が正常であることを理由に、例外オブジェクトのための高いアライメントを与えるために変更を加えました__attribute__((aligned))
と宣言され、16バイトのアライメントが保証されます。 libC++ abiは構造体を__attribute__((aligned))
と宣言していないことが判明し、32ビットおよび64ビットプラットフォームでは8バイトのアラインメントしか保証されません。これにより、バックエンドがSIMDストア命令を発行したときに、16バイトのアラインメントが必要な場合(たとえば、movaps
)、クラッシュが発生しました。
このパッチは、Darwin上でItaniumCXXABI :: getAlignmentOfExnObjectが8バイト境界整列を返してクラッシュを修正します。
..このパッチは、2016年3月31日にr264998としてコミットされました。
https://llvm.org/bugs/show_bug.cgi?id=24604とhttps://llvm.org/bugs/show_bug.cgi?id=27208も表示されます。
更新日 Xcode 7.3をインストールしました。1(昨日リリースされた)、問題は修正されているようだ。生成されたアセンブリは、以下のようになります。
a.out`main:
0x100000ac0 : pushq %rbp
0x100000ac1 : movq %rsp, %rbp
0x100000ac4 : subq $0x20, %rsp
0x100000ac8 : movl $0x0, -0x4(%rbp)
0x100000acf : movl $0x10, %eax
0x100000ad4 : movl %eax, %edi
0x100000ad6 : callq 0x100000dea ; symbol stub for: __cxa_allocate_exception
0x100000adb : movq %rax, %rdi
0x100000ade : movq $0x0, 0x8(%rax)
0x100000ae6 : movq $0x0, (%rax)
0x100000aed : movq %rdi, -0x20(%rbp)
0x100000af1 : movq %rax, %rdi
0x100000af4 : callq 0x100000b40 ; my_exception::my_exception
...
グレート答え!この小さなコードがコンパイラを壊すとは思えません。パッチがすぐにプッシュされることを願って...ありがとう! – mfontanini
@mfontaniniパッチがすでにプッシュされているようです。私はclang-703.0.31/Xcode 7.3.1をテストし、生成されたアセンブリはもはや 'movaps'命令を使用しません。 –