Joakim <[email protected]> writes: > On Monday, 4 January 2016 at 09:26:39 UTC, Dan Olson wrote: >> Joakim <[email protected]> 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
