Skip to content

Commit 3634594

Browse files
committed
runtime: start ARM atomic kernel helper traceback in caller
Like the VDSO, we cannot directly traceback from the Linux kernel ARM atomic/barrier helpers. However, unlike the VDSO, this functions are extremely simple. Neither of the functions we use, kuser_cmpxchg and kuser_memory_barrier, touch SP or LR. We can use this to our advantage to read LR and simply start tracebacks in the caller. Fixes #49182 Change-Id: I890edbeb7c128938000fe7baf6f913c02a956edd Reviewed-on: https://go-review.googlesource.com/c/go/+/362977 Trust: Michael Pratt <[email protected]> Run-TryBot: Michael Pratt <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Cherry Mui <[email protected]>
1 parent 76fbd61 commit 3634594

File tree

1 file changed

+14
-0
lines changed

1 file changed

+14
-0
lines changed

src/runtime/traceback.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,20 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
9696
}
9797
}
9898

99+
// runtime/internal/atomic functions call into kernel helpers on
100+
// arm < 7. See runtime/internal/atomic/sys_linux_arm.s.
101+
//
102+
// Start in the caller's frame.
103+
if GOARCH == "arm" && goarm < 7 && GOOS == "linux" && frame.pc&0xffff0000 == 0xffff0000 {
104+
// Note that the calls are simple BL without pushing the return
105+
// address, so we use LR directly.
106+
//
107+
// The kernel helpers are frameless leaf functions, so SP and
108+
// LR are not touched.
109+
frame.pc = frame.lr
110+
frame.lr = 0
111+
}
112+
99113
f := findfunc(frame.pc)
100114
if !f.valid() {
101115
if callback != nil || printing {

0 commit comments

Comments
 (0)