Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime: binary analysis failed due to fake PC in gosave_systemstack_switch #71440

Open
RuoxiiWaa opened this issue Jan 26, 2025 · 2 comments
Open
Labels
BugReport Issues describing a possible bug in the Go implementation. compiler/runtime Issues related to the Go compiler and/or runtime. WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.

Comments

@RuoxiiWaa
Copy link

Go version

go version go 1.22.6 linux/amd64

Output of go env in your module/workspace:

GO111MODULE='on'
GOARCH='amd64'
GOBIN=''
GOCACHE='/usr1/.cache/go-build'
GOENV='/root/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/opt/go_workpace/pkg/mod'
GONOSUMDB='*'
GOOS='linux'
GOPATH='/opt/go_workpace'
GOROOT='/root/tt/go-go1.22.6/'
GOSUMDB='off'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/root/tt/go-go1.22.6/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.22.6'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build4051586591=/tmp/go-build -gno-record-gcc-switches'

What did you do?

Hi, I want to build CFG of one binary but when I try to track the destination address of the instruction
4735a0: 4c 8d 0d 21 0e 00 00 lea 0xe21(%rip),%r9 # 4743c8 <runtime.systemstack_switch.abi0+0x8> ,
this address is in the middle of one instruction and causes a fault.

gosave_systemstack_switch:

00000000004735a0 <gosave_systemstack_switch>:
  4735a0:       4c 8d 0d 21 0e 00 00    lea    0xe21(%rip),%r9        # 4743c8 <runtime.systemstack_switch.abi0+0x8>
  4735a7:       4d 89 4e 40             mov    %r9,0x40(%r14)
  4735ab:       4c 8d 4c 24 08          lea    0x8(%rsp),%r9
  4735b0:       4d 89 4e 38             mov    %r9,0x38(%r14)
  4735b4:       49 c7 46 58 00 00 00    movq   $0x0,0x58(%r14)
  4735bb:       00
  4735bc:       49 89 6e 68             mov    %rbp,0x68(%r14)
  4735c0:       4d 8b 4e 50             mov    0x50(%r14),%r9
  4735c4:       4d 85 c9                test   %r9,%r9
  4735c7:       74 05                   je     4735ce <gosave_systemstack_switch+0x2e>
  4735c9:       e8 12 2b 00 00          call   4760e0 <runtime.abort.abi0>
  4735ce:       c3                      ret

runtime.systemstack_switch.abi0:

00000000004743c0 <runtime.systemstack_switch.abi0>:
  4743c0:       55                      push   %rbp
  4743c1:       48 89 e5                mov    %rsp,%rbp
  4743c4:       0f 0b                   ud2
  4743c6:       e8 15 1d 00 00          call   4760e0 <runtime.abort.abi0>
  4743cb:       5d                      pop    %rbp
  4743cc:       c3                      ret

What did you see happen?

Since the value here is in the middle of instruction, I couldn't finish CFG build work.

What did you expect to see?

The explanation for the "+8" in function gosave_systemstack_switch is to skip the prologue. And the prologue of amd64 should be 4 bytes, maybe better to change this vaule to 4?

gosave_systemstack_switch in runtime/asm_amd64.s:

// Save state of caller into g->sched,
// but using fake PC from systemstack_switch.
// Must only be called from functions with frame pointer
// and without locals ($0) or else unwinding from
// systemstack_switch is incorrect.
// Smashes R9.
TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
	// Take systemstack_switch PC and add 8 bytes to skip
	// the prologue. The final location does not matter
	// as long as we are between the prologue and the epilogue.
	MOVQ	$runtime·systemstack_switch+8(SB), R9
	MOVQ	R9, (g_sched+gobuf_pc)(R14)
	LEAQ	8(SP), R9
	MOVQ	R9, (g_sched+gobuf_sp)(R14)
	MOVQ	$0, (g_sched+gobuf_ret)(R14)
	MOVQ	BP, (g_sched+gobuf_bp)(R14)
	// Assert ctxt is zero. See func save.
	MOVQ	(g_sched+gobuf_ctxt)(R14), R9
	TESTQ	R9, R9
	JZ	2(PC)
	CALL	runtime·abort(SB)
	RET
@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Jan 26, 2025
@gabyhelp gabyhelp added the BugReport Issues describing a possible bug in the Go implementation. label Jan 26, 2025
@cagedmantis cagedmantis changed the title runtime: Binary analysis failed due to fake PC in gosave_systemstack_switch runtime: binary analysis failed due to fake PC in gosave_systemstack_switch Jan 27, 2025
@prattmic
Copy link
Member

Could you explain a bit more about what you are trying to do? The purpose of this function is only to appear in stack traces, it should never be executed. Thus I am confused by how it "caused a fault".

@cagedmantis cagedmantis added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Jan 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BugReport Issues describing a possible bug in the Go implementation. compiler/runtime Issues related to the Go compiler and/or runtime. WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Projects
Status: No status
Development

No branches or pull requests

5 participants