-
-
Notifications
You must be signed in to change notification settings - Fork 255
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OS X: runnable/testabi.d segmentation fault due to unaligned data #1252
Comments
One workaround is using the existing private align(16) ubyte dummyTlsSymbol = 42; runnable/testabi.d now passes. |
Very nice and detailed analysis, thx for investigating, it was a nice read! :) |
@smolt: Could you please do the change to dummyTlsSymbol (with a short comment and reference to this issue)? |
Yes, it was fortunate that we already had a dummy variable for this purpose. Are there any x86 instructions that require greater that 16-byte alignment? |
Align and initialize dummyTlsSymbol to force __thread_data section alignment to 16-bytes. This is needed to obey __thread_bss section alignments.
Filed 24221680 with Apple. |
Workaround for issue ldc-developers/ldc#1252
Workaround issue ldc-developers#1252 runnable/testabi.d segmentation fault on OS X.
Dan fixed the issue with ldc-developers#1252.
Question to all: should this issue be closed because there is a workaround in place or should it stay open because there is an outstanding Apple radar. It would be nice to eventually remove the workaround, as small as it is, but that may be a long time. Perhaps an appropriate label so this Issue can be ignored in queries of what to work on next? |
Upstream = Apple in this case ;) |
Apple fixed bug 24221680 as of Xcode 8.0. The workaround in druntime could be removed at some future date when Xcode 7 has disappeared. |
edit: workaround in druntime, waiting on Apple radar 24221680.
This is the crash plaguing the OS X release build on Travis right now (commit d3da239).
First of all to leave no surprises, the problem lies outside of LDC as the same crash can be crafted with C code (I'll show it later). So what to do? Document the problem, suggest a workaround, and file a bug report with Apple as I think it is a linker problem.
This problem comes and goes based on the alignment of data being linked. At one time the crash happened when running the 32-bit OS X release version of testabi.d. Now it has moved over to the 64-bit release. It might only happen when LDC has optimizer enabled, but this is not an optimizer error. With clang, you don't even need
-O
to get the same problem.Let's look at a session showing runnable/testabi.d crash.
What is going on here is that the optimizer chose a nice
movdqa
instruction to zero the data inresults_1
(a static array) and requires 16-byte alignment, yetrax
is only 8-bye aligned.LDC asks for the correct alignment though (verified by peeking at LLVM IR and the assembly code):
The 4 is alignment as a power of 2, so LDC is in the clear. Compiling with
-c
and runningnm
on the .o file show a 16-byte aligned relative address for results_1.otool
shows__thread_bss
section as 16-byte aligned. Yet the final linked executable has result_1 only 8-byte aligned. Sure seems like a linker problem.What appears to be going on is the linker creates the thread local layout by concatenating the
__thread_data
and__thread_bss
sections. If__thread_data
does not have same alignment requirements, then there can be problems. In this caseotool
shows__thread_data
only needs 8-byte alignment.tls.c
is a simple yet specially crafted C program that illustrates all of this:Proof that
zb16
is 16-byte aligned by clang:$ clang tls_fail.c -S -emit-llvm $ grep 'zb16.*align' tls_fail.ll @zb16 = thread_local global [16 x i8] zeroinitializer, align 16
Then running
tls_fail
has same segmentation fault ending.-O
not even needed.Dumping the symbol addresses with
nm
shows how the variables are properly aligned as a whole.The
$tlv$init
symbols are the template for each thread local. Here_zb16$tlv$init
is aligned to 16-bytes. But when the thread local data layout is created for_tb$tlv$init
(__thread_data
) and_zb16$tlv$init
(__thread_bss
), it is offset from beginning of__thread_data
0x1049 meaningzb16
0x1050 - 0x1049 = 7 offset (seeprintf
of 0x100104bf7 above).Workaround? It seems having a maximally aligned member in
__thread_data
might do the trick. Maybe we can just have LDC emit a dummy member in the meantime.The text was updated successfully, but these errors were encountered: