Better watch out! D runs on watchOS!

Dan Olson via Digitalmars-d-announce digitalmars-d-announce at puremagic.com
Mon Jan 4 09:54:01 PST 2016


Joakim <dlang at joakim.fea.st> writes:

> On Monday, 4 January 2016 at 09:26:39 UTC, Dan Olson wrote:
>> Joakim <dlang at joakim.fea.st> writes:
>
>> The bug is a bad stack pointer which blows up when the last unittest
>> returns.  This unittest has all the right conditions to generate
>> stack adjustments around some of the function calls that throw
>> exceptions. The exception landing pad does not fixup the stack
>> adjustment, thus a stack leak on each caught exception.  The
>> unittest function epilog restores the stack by adding a fixed offset
>> to match the prolog, so the stack pointer stays wrong when the saved
>> registers and return address are popped.
>>
>> Really looks like LLVM is not doing the right thing with landing
>> pads. In the meantime I patched LLVM to generate epilog that always
>> uses frame pointer to restore the stack pointer.  WatchOS requires a
>> frame pointer, so this isn't too bad.  Now all unittests pass at -O3
>> for watchOS.
>
> Could be the same issue for me, not sure.  If you put your fix online,
> I can try it and see.

It is this commit based on a 2 week old LLVM 3.8 trunk:

https://github.com/smolt/llvm/commit/91a4420615c6ec83b227b63d36054f12ccffb00f

A small change but took me a long time in debugger on an Apple Watch to
figure out.  Something the x86 simulator can't show.  It is tailored to
watchOS which uses thumb2 instructions.  watchOS always has a frame,
hasFP() is always true. You will want to add Android to the hasFP() or
disable frame pointer elimination some other way.  I noticed that
-disable-fp-elim for LDC with LLVM 3.7 and above is broken so can't use
that.

The pattern to look for if you have a suspect is this:

A function that throws an exception is codegened with stack adjustment
surrounding the call:

	sub	sp, #16
	str	r1, [sp]
	mov	r1, r2
	movs	r0, #66
	movw	r2, #2424
	blx	__D3std9exception25__T7bailOutHTC9ExceptionZ7bailOutFNaNfAyakxAaZv
	add	sp, #16    <--- This adjustment is missed on exception

Epilog without hack (llvm 3.8 git 0838b1f Add iOS TLS support for WatchOS)
	itttt	ne
	addne.w	sp, sp, #9984 <-- stack adjust matches prolog, but stack
	                                              is off by 16 bytes if above throws
	addne	sp, #48
	popne.w	{r8, r10, r11}
	popne	{r4, r5, r6, r7, pc}

Epilog with hack (commit 91a4420)
	itttt	ne
	subne.w	r4, r7, #24   <-- stack set from frame pointer (r7)
	movne	sp, r4
	popne.w	{r8, r10, r11}
	popne	{r4, r5, r6, r7, pc}

-- 
Dan


More information about the Digitalmars-d-announce mailing list