Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit 17bfde3

Browse files
authored
Merge pull request #2308 from jpf91/aarch64
[AArch64] [GDC] AArch64: Fix backtraces in Fibers merged-on-behalf-of: David Nadlinger <code@klickverbot.at>
2 parents 565690a + 40c1108 commit 17bfde3

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

src/core/thread.d

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3678,7 +3678,11 @@ private
36783678

36793679
// Look above the definition of 'class Fiber' for some information about the implementation of this routine
36803680
version (AsmExternal)
3681-
extern (C) void fiber_switchContext( void** oldp, void* newp ) nothrow @nogc;
3681+
{
3682+
extern (C) void fiber_switchContext( void** oldp, void* newp ) nothrow @nogc;
3683+
version (AArch64)
3684+
extern (C) void fiber_trampoline() nothrow;
3685+
}
36823686
else
36833687
extern (C) void fiber_switchContext( void** oldp, void* newp ) nothrow @nogc
36843688
{
@@ -4908,7 +4912,7 @@ private:
49084912
// Only need to set return address (lr). Everything else is fine
49094913
// zero initialized.
49104914
pstack -= size_t.sizeof * 11; // skip past x19-x29
4911-
push(cast(size_t) &fiber_entryPoint);
4915+
push(cast(size_t) &fiber_trampoline); // see threadasm.S for docs
49124916
pstack += size_t.sizeof; // adjust sp (newp) above lr
49134917
}
49144918
else version (AsmARM_Posix)

src/core/threadasm.S

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,7 @@ fiber_switchContext:
475475
.text
476476
.global CSYM(fiber_switchContext)
477477
.p2align 2
478+
.type fiber_switchContext, %function
478479
CSYM(fiber_switchContext):
479480
stp d15, d14, [sp, #-20*8]!
480481
stp d13, d12, [sp, #2*8]
@@ -504,4 +505,26 @@ CSYM(fiber_switchContext):
504505
ldp d13, d12, [sp, #2*8]
505506
ldp d15, d14, [sp], #20*8
506507
ret
508+
509+
/**
510+
* When generating any kind of backtrace (gdb, exception handling) for
511+
* a function called in a Fiber, we need to tell the unwinder to stop
512+
* at our Fiber main entry point, i.e. we need to mark the bottom of
513+
* the call stack. This can be done by clearing the link register lr
514+
* prior to calling fiber_entryPoint (i.e. in fiber_switchContext) or
515+
* using a .cfi_undefined directive for the link register in the
516+
* Fiber entry point. cfi_undefined seems to yield better results in gdb.
517+
* Unfortunately we can't place it into fiber_entryPoint using inline
518+
* asm, so we use this trampoline instead.
519+
*/
520+
.text
521+
.global CSYM(fiber_trampoline)
522+
.p2align 2
523+
.type fiber_trampoline, %function
524+
CSYM(fiber_trampoline):
525+
.cfi_startproc
526+
.cfi_undefined x30
527+
// fiber_entryPoint never returns
528+
bl fiber_entryPoint
529+
.cfi_endproc
507530
#endif

0 commit comments

Comments
 (0)