go: runtime: panic not generating a correct backtrace stack while crashing in cgo

What version of Go are you using (go version)?

$ go version
go version go1.21.1 linux/amd64

Does this issue reproduce with the latest release?

Yes.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/root/.cache/go-build'
GOENV='/root/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/root/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/root/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.21.1'
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-build4191549828=/tmp/go-build -gno-record-gcc-switches'

What did you do?

I’m writing a Golang+CGO program, and testing a bad code in CGO to check if it could catch the right backtrace. Different versions of Go give me different outputs, and it’s working in go1.18.3, but not working on go1.21.1 and the latest gotip version(go version devel go1.22-1176052 Thu Sep 28 03:38:07 2023 +0000 linux/amd64).

Like the backtrace from go1.18.3, I would expected it to give the right backtrace which caused the crash. I noticed that if it generates fatal error: unexpected signal during runtime execution and with runtime stack: in the stdout, then it’s correct. Otherwise, it is not correct. Extracting the C code would give me the right backtrace btw.

What did you expect to see?

Generating the correct backtrace(details will be in the Details section).

What did you see instead?

It’s not generating the correct backtrace(details will be in the Details section).

Details

go1.18.3 from the backtrace, we can see the crash is from core function which in frame 14:

(gdb) bt
#0  runtime.raise () at /usr/local/go/src/runtime/sys_linux_amd64.s:168
#1  0x0000000000447e45 in runtime.dieFromSignal (sig=6) at /usr/local/go/src/runtime/signal_unix.go:852
#2  0x0000000000448445 in runtime.sigfwdgo (sig=6, info=<optimized out>, ctx=<optimized out>, ~r0=<optimized out>) at /usr/local/go/src/runtime/signal_unix.go:1066
#3  0x0000000000446e67 in runtime.sigtrampgo (sig=0, info=0xc00000b208, ctx=0x4602e1 <runtime.raise+33>) at /usr/local/go/src/runtime/signal_unix.go:430
#4  0x000000000046108e in runtime.sigtrampgo (sig=6, info=0xc00000b4b0, ctx=0xc00000b380) at <autogenerated>:1
#5  0x00000000004605bd in runtime.sigtramp () at /usr/local/go/src/runtime/sys_linux_amd64.s:361
#6  <signal handler called>
#7  runtime.raise () at /usr/local/go/src/runtime/sys_linux_amd64.s:168
#8  0x0000000000447e45 in runtime.dieFromSignal (sig=6) at /usr/local/go/src/runtime/signal_unix.go:852
#9  0x0000000000448058 in runtime.crash () at /usr/local/go/src/runtime/signal_unix.go:944
#10 0x0000000000433c71 in runtime.fatalthrow.func1 () at /usr/local/go/src/runtime/panic.go:1051
#11 0x0000000000433bf0 in runtime.fatalthrow () at /usr/local/go/src/runtime/panic.go:1044
#12 0x00000000004339b1 in runtime.throw (s=...) at /usr/local/go/src/runtime/panic.go:992
#13 0x0000000000447de5 in runtime.sigpanic () at /usr/local/go/src/runtime/signal_unix.go:802
#14 0x000000000046e7f0 in core () at /data-share/badstack/main.go:20
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

std:

fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x46e7f0]

runtime stack:
runtime.throw({0x486e64?, 0x40bb79?})
	/usr/local/go/src/runtime/panic.go:992 +0x71 fp=0x7ffd80fa4310 sp=0x7ffd80fa42e0 pc=0x4339b1
runtime.sigpanic()
	/usr/local/go/src/runtime/signal_unix.go:802 +0x225 fp=0x7ffd80fa4340 sp=0x7ffd80fa4310 pc=0x447de5

goroutine 1 [syscall]:
runtime.cgocall(0x46e8e0, 0xc00010df50)
	/usr/local/go/src/runtime/cgocall.go:157 +0x5c fp=0xc00010df28 sp=0xc00010def0 pc=0x403f3c
main._Cfunc_core_logic()
	_cgo_gotypes.go:41 +0x45 fp=0xc00010df50 sp=0xc00010df28 pc=0x46e725
main.coreLogic()
	/data-share/badstack/main.go:48 +0x17 fp=0xc00010df60 sp=0xc00010df50 pc=0x46e777
main.main()
	/data-share/badstack/main.go:55 +0x2a fp=0xc00010df80 sp=0xc00010df60 pc=0x46e7ca
runtime.main()
	/usr/local/go/src/runtime/proc.go:250 +0x1d8 fp=0xc00010dfe0 sp=0xc00010df80 pc=0x436038
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:1571 +0x1 fp=0xc00010dfe8 sp=0xc00010dfe0 pc=0x45ea01

goroutine 2 [force gc (idle)]:
runtime.gopark(0x488500, 0x6ea590, 0x11, 0x14, 0x1)
	/usr/local/go/src/runtime/proc.go:361 +0xf2 fp=0xc000046f88 sp=0xc000046f58 pc=0x436452
runtime.goparkunlock(0x0?, 0x0?, 0x0?, 0x0?)
	/usr/local/go/src/runtime/proc.go:367 +0x2a fp=0xc000046fb8 sp=0xc000046f88 pc=0x4364ea
runtime.forcegchelper()
	/usr/local/go/src/runtime/proc.go:301 +0xa5 fp=0xc000046fe0 sp=0xc000046fb8 pc=0x436285
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:1571 +0x1 fp=0xc000046fe8 sp=0xc000046fe0 pc=0x45ea01
created by runtime.init.6
	/usr/local/go/src/runtime/proc.go:289 +0x25

goroutine 3 [GC sweep wait]:
runtime.gopark(0x488500, 0x6ea720, 0xc, 0x14, 0x1)
	/usr/local/go/src/runtime/proc.go:361 +0xf2 fp=0xc000047768 sp=0xc000047738 pc=0x436452
runtime.goparkunlock(0x0?, 0x0?, 0x0?, 0x0?)
	/usr/local/go/src/runtime/proc.go:367 +0x2a fp=0xc000047798 sp=0xc000047768 pc=0x4364ea
runtime.bgsweep(0x0?)
	/usr/local/go/src/runtime/mgcsweep.go:278 +0x98 fp=0xc0000477c8 sp=0xc000047798 pc=0x421ab8
runtime.gcenable.func1()
	/usr/local/go/src/runtime/mgc.go:177 +0x26 fp=0xc0000477e0 sp=0xc0000477c8 pc=0x4179a6
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:1571 +0x1 fp=0xc0000477e8 sp=0xc0000477e0 pc=0x45ea01
created by runtime.gcenable
	/usr/local/go/src/runtime/mgc.go:177 +0x6b

goroutine 4 [GC scavenge wait]:
runtime.gopark(0x488500, 0x6ea6e0, 0xd, 0x14, 0x1)
	/usr/local/go/src/runtime/proc.go:361 +0xf2 fp=0xc000047ef0 sp=0xc000047ec0 pc=0x436452
runtime.goparkunlock(0x0?, 0x0?, 0x0?, 0x0?)
	/usr/local/go/src/runtime/proc.go:367 +0x2a fp=0xc000047f20 sp=0xc000047ef0 pc=0x4364ea
runtime.bgscavenge(0x0?)
	/usr/local/go/src/runtime/mgcscavenge.go:272 +0xed fp=0xc000047fc8 sp=0xc000047f20 pc=0x41f54d
runtime.gcenable.func2()
	/usr/local/go/src/runtime/mgc.go:178 +0x26 fp=0xc000047fe0 sp=0xc000047fc8 pc=0x417946
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:1571 +0x1 fp=0xc000047fe8 sp=0xc000047fe0 pc=0x45ea01
created by runtime.gcenable
	/usr/local/go/src/runtime/mgc.go:178 +0xaa

goroutine 5 [finalizer wait]:
runtime.gopark(0x488500, 0x719890, 0x10, 0x14, 0x1)
	/usr/local/go/src/runtime/proc.go:361 +0xf2 fp=0xc000046600 sp=0xc0000465d0 pc=0x436452
runtime.goparkunlock(0x0?, 0x60?, 0x66?, 0xc000046770?)
	/usr/local/go/src/runtime/proc.go:367 +0x2a fp=0xc000046630 sp=0xc000046600 pc=0x4364ea
runtime.runfinq()
	/usr/local/go/src/runtime/mfinal.go:177 +0xab fp=0xc0000467e0 sp=0xc000046630 pc=0x416a2b
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:1571 +0x1 fp=0xc0000467e8 sp=0xc0000467e0 pc=0x45ea01
created by runtime.createfing
	/usr/local/go/src/runtime/mfinal.go:157 +0x45
Aborted (core dumped)

go1.21.1 from the backtrace, we can not tell which function cause this crash:

(gdb) bt
#0  runtime.raise () at /usr/local/go/src/runtime/sys_linux_amd64.s:154
#1  0x000000000044b0c5 in runtime.dieFromSignal (sig=6) at /usr/local/go/src/runtime/signal_unix.go:903
#2  0x000000000044b755 in runtime.sigfwdgo (sig=6, info=<optimized out>, ctx=<optimized out>, ~r0=<optimized out>) at /usr/local/go/src/runtime/signal_unix.go:1108
#3  0x000000000044a025 in runtime.sigtrampgo (sig=0, info=0xc0001063b0, ctx=0x4642a1 <runtime.raise+33>) at /usr/local/go/src/runtime/signal_unix.go:432
#4  0x0000000000464586 in runtime.sigtramp () at /usr/local/go/src/runtime/sys_linux_amd64.s:352
#5  <signal handler called>
#6  runtime.raise () at /usr/local/go/src/runtime/sys_linux_amd64.s:154
#7  0x000000000044b0c5 in runtime.dieFromSignal (sig=6) at /usr/local/go/src/runtime/signal_unix.go:903
#8  0x000000000044b2b2 in runtime.crash () at /usr/local/go/src/runtime/signal_unix.go:985
#9  0x000000000044a9c5 in runtime.sighandler (sig=3, info=<optimized out>, ctxt=<optimized out>, gp=0xc000007860) at /usr/local/go/src/runtime/signal_unix.go:771
#10 0x000000000044a151 in runtime.sigtrampgo (sig=3, info=0xc0001074b0, ctx=0xc000107380) at /usr/local/go/src/runtime/signal_unix.go:490
#11 0x0000000000464586 in runtime.sigtramp () at /usr/local/go/src/runtime/sys_linux_amd64.s:352
#12 <signal handler called>
#13 runtime.futex () at /usr/local/go/src/runtime/sys_linux_amd64.s:557
#14 0x00000000004321f0 in runtime.futexsleep (addr=0xca, val=0, ns=4605987) at /usr/local/go/src/runtime/os_linux.go:69
#15 0x000000000040b77d in runtime.notesleep (n=0x713e58 <runtime.newmHandoff+24>) at /usr/local/go/src/runtime/lock_futex.go:160
#16 0x000000000043c6e5 in runtime.templateThread () at /usr/local/go/src/runtime/proc.go:2514
#17 0x000000000043b1d3 in runtime.mstart1 () at /usr/local/go/src/runtime/proc.go:1600
#18 0x000000000043b125 in runtime.mstart0 () at /usr/local/go/src/runtime/proc.go:1557
#19 0x0000000000460a45 in runtime.mstart () at /usr/local/go/src/runtime/asm_amd64.s:394
#20 0x000000000046c848 in crosscall_amd64 () at gcc_amd64.S:42
#21 0x00007f36cffff700 in ?? ()
#22 0x000000c000007860 in ?? ()
#23 0x0000000000a01000 in ?? ()
#24 0x0000000000000000 in ?? ()

std:

SIGSEGV: segmentation violation
PC=0x46bd10 m=0 sigcode=1
signal arrived during cgo execution

goroutine 1 [syscall]:
runtime.cgocall(0x46be00, 0xc00005df38)
	/usr/local/go/src/runtime/cgocall.go:157 +0x4b fp=0xc00005df10 sp=0xc00005ded8 pc=0x40506b
main._Cfunc_core_logic()
	_cgo_gotypes.go:39 +0x3f fp=0xc00005df38 sp=0xc00005df10 pc=0x46bc5f
main.coreLogic()
	/data-share/badstack/main.go:48 +0xf fp=0xc00005df48 sp=0xc00005df38 pc=0x46bc8f
main.main()
	/data-share/badstack/main.go:55 +0x25 fp=0xc00005df68 sp=0xc00005df48 pc=0x46bce5
runtime.main()
	/usr/local/go/src/runtime/proc.go:267 +0x267 fp=0xc00005dfe0 sp=0xc00005df68 pc=0x438627
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:1650 +0x1 fp=0xc00005dfe8 sp=0xc00005dfe0 pc=0x462ac1

goroutine 2 [force gc (idle)]:
runtime.gopark(0x486da8, 0x6e5850, 0x11, 0x14, 0x1)
	/usr/local/go/src/runtime/proc.go:398 +0xfc fp=0xc000048f80 sp=0xc000048f50 pc=0x438a9c
runtime.goparkunlock(0x0?, 0x0?, 0x0?, 0x0?)
	/usr/local/go/src/runtime/proc.go:404 +0x25 fp=0xc000048fb0 sp=0xc000048f80 pc=0x438b25
runtime.forcegchelper()
	/usr/local/go/src/runtime/proc.go:322 +0xb5 fp=0xc000048fe0 sp=0xc000048fb0 pc=0x4388b5
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:1650 +0x1 fp=0xc000048fe8 sp=0xc000048fe0 pc=0x462ac1
created by runtime.init.6 in goroutine 1
	/usr/local/go/src/runtime/proc.go:310 +0x1a

goroutine 3 [GC sweep wait]:
runtime.gopark(0x486da8, 0x6e5a00, 0xc, 0x14, 0x1)
	/usr/local/go/src/runtime/proc.go:398 +0xfc fp=0xc000049750 sp=0xc000049720 pc=0x438a9c
runtime.goparkunlock(0x0?, 0x0?, 0x0?, 0x0?)
	/usr/local/go/src/runtime/proc.go:404 +0x25 fp=0xc000049780 sp=0xc000049750 pc=0x438b25
runtime.bgsweep(0x0?)
	/usr/local/go/src/runtime/mgcsweep.go:280 +0xa5 fp=0xc0000497c8 sp=0xc000049780 pc=0x423105
runtime.gcenable.func1()
	/usr/local/go/src/runtime/mgc.go:200 +0x25 fp=0xc0000497e0 sp=0xc0000497c8 pc=0x4175c5
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:1650 +0x1 fp=0xc0000497e8 sp=0xc0000497e0 pc=0x462ac1
created by runtime.gcenable in goroutine 1
	/usr/local/go/src/runtime/mgc.go:200 +0x66

goroutine 4 [GC scavenge wait]:
runtime.gopark(0x486da8, 0x6e5a80, 0xd, 0x14, 0x2)
	/usr/local/go/src/runtime/proc.go:398 +0xfc fp=0xc000049f40 sp=0xc000049f10 pc=0x438a9c
runtime.goparkunlock(0x489650?, 0x1?, 0x0?, 0xc0000071e0?)
	/usr/local/go/src/runtime/proc.go:404 +0x25 fp=0xc000049f70 sp=0xc000049f40 pc=0x438b25
runtime.(*scavengerState).park(0x6e5a80)
	/usr/local/go/src/runtime/mgcscavenge.go:425 +0x45 fp=0xc000049f98 sp=0xc000049f70 pc=0x4203e5
runtime.bgscavenge(0x0?)
	/usr/local/go/src/runtime/mgcscavenge.go:653 +0x45 fp=0xc000049fc8 sp=0xc000049f98 pc=0x420945
runtime.gcenable.func2()
	/usr/local/go/src/runtime/mgc.go:201 +0x25 fp=0xc000049fe0 sp=0xc000049fc8 pc=0x417565
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:1650 +0x1 fp=0xc000049fe8 sp=0xc000049fe0 pc=0x462ac1
created by runtime.gcenable in goroutine 1
	/usr/local/go/src/runtime/mgc.go:201 +0xa5

goroutine 5 [finalizer wait]:
runtime.gopark(0x486cb0, 0x713bc0, 0x10, 0x14, 0x1)
	/usr/local/go/src/runtime/proc.go:398 +0xfc fp=0xc000048628 sp=0xc0000485f8 pc=0x438a9c
runtime.runfinq()
	/usr/local/go/src/runtime/mfinal.go:193 +0xfa fp=0xc0000487e0 sp=0xc000048628 pc=0x41667a
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:1650 +0x1 fp=0xc0000487e8 sp=0xc0000487e0 pc=0x462ac1
created by runtime.createfing in goroutine 1
	/usr/local/go/src/runtime/mfinal.go:163 +0x45

rax    0x0
rbx    0x7ffd40b52e80
rcx    0x100000
rdx    0x7ffd40a52e90
rdi    0x713318
rsi    0x6e5b20
rbp    0x7ffd40b52e70
rsp    0x7ffd40b52e70
r8     0x6e5f00
r9     0x0
r10    0x8
r11    0x206
r12    0xc00005dca0
r13    0xffffffffffffffff
r14    0xc0000061a0
r15    0x2031
rip    0x46bd10
rflags 0x10246
cs     0x33
fs     0x0
gs     0x0

-----

SIGQUIT: quit
PC=0x464823 m=2 sigcode=0

goroutine 0 [idle]:
runtime.futex()
	/usr/local/go/src/runtime/sys_linux_amd64.s:558 +0x23 fp=0x7f36d6ebcd20 sp=0x7f36d6ebcd18 pc=0x464823
runtime.futexsleep(0x40b513?, 0x40b55e?, 0x7f36d6ebcdd0?)
	/usr/local/go/src/runtime/os_linux.go:75 +0x98 fp=0x7f36d6ebcd80 sp=0x7f36d6ebcd20 pc=0x432258
runtime.notetsleep_internal(0x6e6400, 0xdf8475800)
	/usr/local/go/src/runtime/lock_futex.go:202 +0xbb fp=0x7f36d6ebcdc0 sp=0x7f36d6ebcd80 pc=0x40b89b
runtime.notetsleep(0xb6500000014?, 0x7f3600000008?)
	/usr/local/go/src/runtime/lock_futex.go:225 +0x29 fp=0x7f36d6ebcde0 sp=0x7f36d6ebcdc0 pc=0x40b9c9
runtime.sysmon()
	/usr/local/go/src/runtime/proc.go:5570 +0x1d6 fp=0x7f36d6ebce60 sp=0x7f36d6ebcde0 pc=0x442f36
runtime.mstart1()
	/usr/local/go/src/runtime/proc.go:1600 +0x93 fp=0x7f36d6ebce88 sp=0x7f36d6ebce60 pc=0x43b1d3
runtime.mstart0()
	/usr/local/go/src/runtime/proc.go:1557 +0x85 fp=0x7f36d6ebcec0 sp=0x7f36d6ebce88 pc=0x43b125
runtime.mstart()
	/usr/local/go/src/runtime/asm_amd64.s:394 +0x5 fp=0x7f36d6ebcec8 sp=0x7f36d6ebcec0 pc=0x460a45
rax    0xfffffffffffffffc
rbx    0x0
rcx    0x464823
rdx    0x0
rdi    0x6e6400
rsi    0x80
rbp    0x7f36d6ebcd70
rsp    0x7f36d6ebcd18
r8     0x0
r9     0x0
r10    0x7f36d6ebcd58
r11    0x246
r12    0x7f36d6ebcd48
r13    0xa01000
r14    0xc0000069c0
r15    0x7f36d6ebd700
rip    0x464823
rflags 0x246
cs     0x33
fs     0x0
gs     0x0

-----

SIGQUIT: quit
PC=0x464821 m=3 sigcode=0

goroutine 0 [idle]:
runtime.futex()
	/usr/local/go/src/runtime/sys_linux_amd64.s:557 +0x21 fp=0x7f36d64bbbe8 sp=0x7f36d64bbbe0 pc=0x464821
runtime.futexsleep(0x40b55e?, 0xd64bbc68?, 0x40bbb3?)
	/usr/local/go/src/runtime/os_linux.go:69 +0x30 fp=0x7f36d64bbc48 sp=0x7f36d64bbbe8 pc=0x4321f0
runtime.notesleep(0xc00004e948)
	/usr/local/go/src/runtime/lock_futex.go:160 +0x9d fp=0x7f36d64bbc80 sp=0x7f36d64bbc48 pc=0x40b77d
runtime.mPark()
	/usr/local/go/src/runtime/proc.go:1632 +0x1e fp=0x7f36d64bbca0 sp=0x7f36d64bbc80 pc=0x43b2be
runtime.stopm()
	/usr/local/go/src/runtime/proc.go:2536 +0x6d fp=0x7f36d64bbcc8 sp=0x7f36d64bbca0 pc=0x43c7ed
runtime.gcstopm()
	/usr/local/go/src/runtime/proc.go:2835 +0xb6 fp=0x7f36d64bbcf8 sp=0x7f36d64bbcc8 pc=0x43d176
runtime.findRunnable()
	/usr/local/go/src/runtime/proc.go:2901 +0x65 fp=0x7f36d64bbe18 sp=0x7f36d64bbcf8 pc=0x43d3a5
runtime.schedule()
	/usr/local/go/src/runtime/proc.go:3582 +0xbd fp=0x7f36d64bbe50 sp=0x7f36d64bbe18 pc=0x43ea7d
runtime.park_m(0xc000006b60?)
	/usr/local/go/src/runtime/proc.go:3745 +0x105 fp=0x7f36d64bbe80 sp=0x7f36d64bbe50 pc=0x43efe5
runtime.mcall()
	/usr/local/go/src/runtime/asm_amd64.s:458 +0x4e fp=0x7f36d64bbe98 sp=0x7f36d64bbe80 pc=0x460ace
rax    0xca
rbx    0x0
rcx    0x464823
rdx    0x0
rdi    0xc00004e948
rsi    0x80
rbp    0x7f36d64bbc38
rsp    0x7f36d64bbbe0
r8     0x0
r9     0x0
r10    0x0
r11    0x286
r12    0x7f36d64bbc88
r13    0xffffffffffffffff
r14    0xc000006ea0
r15    0x2031
rip    0x464821
rflags 0x286
cs     0x33
fs     0x0
gs     0x0

-----

SIGQUIT: quit
PC=0x464821 m=4 sigcode=0

goroutine 0 [idle]:
runtime.futex()
	/usr/local/go/src/runtime/sys_linux_amd64.s:557 +0x21 fp=0x7f36d5abad10 sp=0x7f36d5abad08 pc=0x464821
runtime.futexsleep(0x40b55e?, 0xd5abad90?, 0x40bbb3?)
	/usr/local/go/src/runtime/os_linux.go:69 +0x30 fp=0x7f36d5abad70 sp=0x7f36d5abad10 pc=0x4321f0
runtime.notesleep(0xc00004ed48)
	/usr/local/go/src/runtime/lock_futex.go:160 +0x9d fp=0x7f36d5abada8 sp=0x7f36d5abad70 pc=0x40b77d
runtime.mPark()
	/usr/local/go/src/runtime/proc.go:1632 +0x1e fp=0x7f36d5abadc8 sp=0x7f36d5abada8 pc=0x43b2be
runtime.stopm()
	/usr/local/go/src/runtime/proc.go:2536 +0x6d fp=0x7f36d5abadf0 sp=0x7f36d5abadc8 pc=0x43c7ed
runtime.startlockedm(0x40b513?)
	/usr/local/go/src/runtime/proc.go:2808 +0x71 fp=0x7f36d5abae18 sp=0x7f36d5abadf0 pc=0x43d071
runtime.schedule()
	/usr/local/go/src/runtime/proc.go:3628 +0x6d fp=0x7f36d5abae50 sp=0x7f36d5abae18 pc=0x43ea2d
runtime.park_m(0xc000007040?)
	/usr/local/go/src/runtime/proc.go:3745 +0x105 fp=0x7f36d5abae80 sp=0x7f36d5abae50 pc=0x43efe5
runtime.mcall()
	/usr/local/go/src/runtime/asm_amd64.s:458 +0x4e fp=0x7f36d5abae98 sp=0x7f36d5abae80 pc=0x460ace
rax    0xca
rbx    0x0
rcx    0x464823
rdx    0x0
rdi    0xc00004ed48
rsi    0x80
rbp    0x7f36d5abad60
rsp    0x7f36d5abad08
r8     0x0
r9     0x0
r10    0x0
r11    0x286
r12    0x7f36d5abad78
r13    0xa01000
r14    0xc000007520
r15    0x7f36d5abb700
rip    0x464821
rflags 0x286
cs     0x33
fs     0x0
gs     0x0

-----

SIGQUIT: quit
PC=0x464821 m=5 sigcode=0

goroutine 0 [idle]:
runtime.futex()
	/usr/local/go/src/runtime/sys_linux_amd64.s:557 +0x21 fp=0x7f36d50b9be8 sp=0x7f36d50b9be0 pc=0x464821
runtime.futexsleep(0x40b55e?, 0xd50b9c68?, 0x40bbb3?)
	/usr/local/go/src/runtime/os_linux.go:69 +0x30 fp=0x7f36d50b9c48 sp=0x7f36d50b9be8 pc=0x4321f0
runtime.notesleep(0xc000080148)
	/usr/local/go/src/runtime/lock_futex.go:160 +0x9d fp=0x7f36d50b9c80 sp=0x7f36d50b9c48 pc=0x40b77d
runtime.mPark()
	/usr/local/go/src/runtime/proc.go:1632 +0x1e fp=0x7f36d50b9ca0 sp=0x7f36d50b9c80 pc=0x43b2be
runtime.stopm()
	/usr/local/go/src/runtime/proc.go:2536 +0x6d fp=0x7f36d50b9cc8 sp=0x7f36d50b9ca0 pc=0x43c7ed
runtime.gcstopm()
	/usr/local/go/src/runtime/proc.go:2835 +0xb6 fp=0x7f36d50b9cf8 sp=0x7f36d50b9cc8 pc=0x43d176
runtime.findRunnable()
	/usr/local/go/src/runtime/proc.go:2901 +0x65 fp=0x7f36d50b9e18 sp=0x7f36d50b9cf8 pc=0x43d3a5
runtime.schedule()
	/usr/local/go/src/runtime/proc.go:3582 +0xbd fp=0x7f36d50b9e50 sp=0x7f36d50b9e18 pc=0x43ea7d
runtime.park_m(0xc000007a00?)
	/usr/local/go/src/runtime/proc.go:3745 +0x105 fp=0x7f36d50b9e80 sp=0x7f36d50b9e50 pc=0x43efe5
runtime.mcall()
	/usr/local/go/src/runtime/asm_amd64.s:458 +0x4e fp=0x7f36d50b9e98 sp=0x7f36d50b9e80 pc=0x460ace
rax    0xca
rbx    0x0
rcx    0x464823
rdx    0x0
rdi    0xc000080148
rsi    0x80
rbp    0x7f36d50b9c38
rsp    0x7f36d50b9be0
r8     0x0
r9     0x0
r10    0x0
r11    0x286
r12    0x7f36d50b9d78
r13    0xa01000
r14    0xc0000821a0
r15    0x7f36d50ba700
rip    0x464821
rflags 0x286
cs     0x33
fs     0x0
gs     0x0

-----

SIGQUIT: quit
PC=0x464821 m=6 sigcode=0

goroutine 0 [idle]:
runtime.futex()
	/usr/local/go/src/runtime/sys_linux_amd64.s:557 +0x21 fp=0x7f36cfffeda0 sp=0x7f36cfffed98 pc=0x464821
runtime.futexsleep(0x40bc13?, 0x713e40?, 0x7f36cfffee28?)
	/usr/local/go/src/runtime/os_linux.go:69 +0x30 fp=0x7f36cfffee00 sp=0x7f36cfffeda0 pc=0x4321f0
runtime.notesleep(0x713e58)
	/usr/local/go/src/runtime/lock_futex.go:160 +0x9d fp=0x7f36cfffee38 sp=0x7f36cfffee00 pc=0x40b77d
runtime.templateThread()
	/usr/local/go/src/runtime/proc.go:2514 +0x65 fp=0x7f36cfffee60 sp=0x7f36cfffee38 pc=0x43c6e5
runtime.mstart1()
	/usr/local/go/src/runtime/proc.go:1600 +0x93 fp=0x7f36cfffee88 sp=0x7f36cfffee60 pc=0x43b1d3
runtime.mstart0()
	/usr/local/go/src/runtime/proc.go:1557 +0x85 fp=0x7f36cfffeec0 sp=0x7f36cfffee88 pc=0x43b125
runtime.mstart()
	/usr/local/go/src/runtime/asm_amd64.s:394 +0x5 fp=0x7f36cfffeec8 sp=0x7f36cfffeec0 pc=0x460a45
rax    0xca
rbx    0x0
rcx    0x464823
rdx    0x0
rdi    0x713e58
rsi    0x80
rbp    0x7f36cfffedf0
rsp    0x7f36cfffed98
r8     0x0
r9     0x0
r10    0x0
r11    0x286
r12    0x0
r13    0xa01000
r14    0xc000007860
r15    0x7f36cffff700
rip    0x464821
rflags 0x286
cs     0x33
fs     0x0
gs     0x0
Aborted (core dumped)

Pure C from the backtrace, we can see the crash is caused by core function in frame 0.

Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x0000000000400660 in core () at main.c:15
15	  *ptr = 1024;
(gdb) bt
#0  0x0000000000400660 in core () at main.c:15
#1  0x00007feccc2cb190 in ?? () from /lib64/libc.so.6
#2  0x0000000000601408 in uctx_core ()
#3  0x0000000000000000 in ?? ()

Reproducer

Please compile with: CC=clang CXX=clang++ CFLAGS="$(cflags)" go build -gcflags="all=-N -l" main.go

package main

/*
#cgo CFLAGS: -g -O0
#include <stdio.h>
#include <stddef.h>
#include <ucontext.h>
#include <stdlib.h>
#include <signal.h>

static ucontext_t uctx_main, uctx_core;

void core()
{
  // core logic


  // trigger crash
  int* ptr = NULL;
  *ptr = 1024;
}

void core_logic()
{
  size_t size = 1024 * 1024;
  char stack[size]; // SIGSEGV
  //void* stack = malloc(size); // SIGTRAP

  if (getcontext(&uctx_core) == -1)
    printf("failed to getcontext");

  uctx_core.uc_stack.ss_sp = stack;
  uctx_core.uc_stack.ss_size = size;
  uctx_core.uc_link = &uctx_main;

  makecontext(&uctx_core, core, 0);

  if (swapcontext(&uctx_main, &uctx_core) == -1)
    printf("failed to swapcontext");

  printf("back\n");
}
*/
import "C"
import "runtime/debug"

func coreLogic() {
  C.core_logic()
}

func main() {
  debug.SetTraceback("crash")

  // Call the C function from Go
  coreLogic()
}

Environment

# clang -v
clang version 10.0.0
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/local/bin
Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/4.8.2
Found candidate GCC installation: /usr/lib/gcc/x86_64-redhat-linux/4.8.5
Selected GCC installation: /usr/lib/gcc/x86_64-redhat-linux/4.8.5
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Selected multilib: .;@m64

# gdb -v
GNU gdb (GDB) 9.1
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Updated on 2023-09-29: I think it’s related to use ucontext in CGO, since if I do not bind function with ucontext, just call core C function directly instead of calling core_logic, the stack backtrace would be fine. And it may has something related to this issue https://github.com/golang/go/issues/62130.

About this issue

  • Original URL
  • State: closed
  • Created 9 months ago
  • Comments: 19 (18 by maintainers)

Most upvoted comments

@zzkcode thanks for the CL. I think it is reasonable to include this CL in Go 1.22 as a bug fix. The risk is very low, as it only affects programs that are already crashing.

I don’t think this needs to be backported. We usually just backport fixes for critical issues with no workaround. This is not critical (the program is crashing either way) and has workarounds (e.g. check all threads in GDB).

Thanks.