From 363459479014bde19e83d9fb6781310f63fb0b45 Mon Sep 17 00:00:00 2001 From: Michael Pratt Date: Wed, 10 Nov 2021 12:56:40 -0500 Subject: [PATCH] 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 Run-TryBot: Michael Pratt TryBot-Result: Go Bot Reviewed-by: Cherry Mui --- src/runtime/traceback.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go index 36627a6735..73bd0e11a9 100644 --- a/src/runtime/traceback.go +++ b/src/runtime/traceback.go @@ -96,6 +96,20 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in } } + // runtime/internal/atomic functions call into kernel helpers on + // arm < 7. See runtime/internal/atomic/sys_linux_arm.s. + // + // Start in the caller's frame. + if GOARCH == "arm" && goarm < 7 && GOOS == "linux" && frame.pc&0xffff0000 == 0xffff0000 { + // Note that the calls are simple BL without pushing the return + // address, so we use LR directly. + // + // The kernel helpers are frameless leaf functions, so SP and + // LR are not touched. + frame.pc = frame.lr + frame.lr = 0 + } + f := findfunc(frame.pc) if !f.valid() { if callback != nil || printing {