proc: fix arm64 crosscall2 SP restore for cgo stacktraces - #4399
Open
derekparker wants to merge 4 commits into
Open
proc: fix arm64 crosscall2 SP restore for cgo stacktraces#4399derekparker wants to merge 4 commits into
derekparker wants to merge 4 commits into
Conversation
derekparker
force-pushed
the
fix/cgo-stacktrace-arm64
branch
from
July 22, 2026 16:49
bf00847 to
c79d5c1
Compare
crosscall2 does SUB $(8*24), RSP but never spills SP. Linux/arm64 was restoring SP from the saved frame pointer, which only works when C frames keep a frame pointer; with newer GCC (Ubuntu 24.04 CI) that omits them, TestCgoStacktrace skips C frames after a cgo callback. Loading *(SP+8*24) is also wrong (that slot is the caller's stack contents). Restore the caller SP as SP+8*24, matching what crosscall2's epilogue adds back.
derekparker
force-pushed
the
fix/cgo-stacktrace-arm64
branch
from
July 23, 2026 17:34
fe786cb to
1071039
Compare
Apply the same SP+framesize restore used on arm64: crosscall2 adjusts SP but does not spill it, so loading from SP+N reads caller stack contents. Also correct ppc64le BP/LR slot offsets from the host ABI save macros, and re-enable TestCgoStacktrace on linux/ppc64le.
The arm64 crosscall2 SP restore fix applies to all GOOS via arm64_arch.go, so re-enable the previously skipped windows/arm64 cgo stacktrace test.
C frames on windows/arm64 use PE .pdata/.xdata from clang, not DWARF .debug_frame. Delve does not unwind via .pdata yet, so step 1 fails inside C before asmcgocall or crosscall2. That is unrelated to the arm64 crosscall2 SP restore this PR fixes.
derekparker
marked this pull request as ready for review
July 28, 2026 18:08
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
crosscall2adjusts SP (e.g.SUB $(8*24), RSPon arm64) but never spills it. Delve was either restoring SP from the saved frame pointer (linux/arm64) or loading*(SP+N)(other LR arches). Both are wrong: the FP fallback only works when C keeps a frame pointer, and*(SP+N)is the caller's stack contents.After the TeamCity Ubuntu 20.04 -> 24.04 bump (newer GCC), cgo-compiled C more often omits frame pointers, so
TestCgoStacktracefailed on linux/arm64 at the C→Go callback step.Restore the caller SP as
SP + framesize, matching what each arch'scrosscall2epilogue adds back. Applied on arm64, riscv64, loong64, and ppc64le (with corrected ppc64le BP/LR save slots). Re-enableTestCgoStacktraceon linux/ppc64le.darwin/arm64 shares the arm64 path and gets the same correct restore.