From 43491f8d52f13df3c70277f81c85809818969d77 Mon Sep 17 00:00:00 2001 From: Ariel Otilibili Date: Sat, 1 Nov 2025 14:20:45 +0000 Subject: [PATCH] cmd/cgo: use the export'ed file/line in error messages When an unpinned Go pointer (or a pointer to an unpinned Go pointer) is returned from Go to C, 1 package main 2 3 import ( 4 "C" 5 ) 6 7 //export foo 8 func foo(CLine *C.char) string { 9 return C.GoString(CLine) 10 } 11 12 13 func main() { 14 } The error message mentions the file/line of the cgo wrapper, panic: runtime error: cgo result is unpinned Go pointer or points to unpinned Go pointer goroutine 17 [running, locked to thread]: panic({0x798f2341a4c0?, 0xc000112000?}) /usr/lib/go/src/runtime/panic.go:802 +0x168 runtime.cgoCheckArg(0x798f23417e20, 0xc000066e50, 0x0?, 0x0, {0x798f233f5a62, 0x42}) /usr/lib/go/src/runtime/cgocall.go:679 +0x35b runtime.cgoCheckResult({0x798f23417e20, 0xc000066e50}) /usr/lib/go/src/runtime/cgocall.go:795 +0x4b _cgoexp_3c910ddb72c4_foo(0x7ffc9fa9bfa0) _cgo_gotypes.go:65 +0x5d runtime.cgocallbackg1(0x798f233ec780, 0x7ffc9fa9bfa0, 0x0) /usr/lib/go/src/runtime/cgocall.go:446 +0x289 runtime.cgocallbackg(0x798f233ec780, 0x7ffc9fa9bfa0, 0x0) /usr/lib/go/src/runtime/cgocall.go:350 +0x132 runtime.cgocallbackg(0x798f233ec780, 0x7ffc9fa9bfa0, 0x0) :1 +0x2b runtime.cgocallback(0x0, 0x0, 0x0) /usr/lib/go/src/runtime/asm_amd64.s:1082 +0xcd runtime.goexit({}) /usr/lib/go/src/runtime/asm_amd64.s:1693 +0x1 The cgo wrapper (_cgoexp_3c910ddb72c4_foo) is located in a temporary build artifact (_cgo_gotypes.go) $ go tool cgo -objdir objdir parse.go $ cat -n objdir/_cgo_gotypes.go | sed -n '55,70p' 55 //go:cgo_export_dynamic foo 56 //go:linkname _cgoexp_d48770e267d1_foo _cgoexp_d48770e267d1_foo 57 //go:cgo_export_static _cgoexp_d48770e267d1_foo 58 func _cgoexp_d48770e267d1_foo(a *struct { 59 p0 *_Ctype_char 60 r0 string 61 }) { 62 a.r0 = foo(a.p0) 63 _cgoCheckResult(a.r0) 64 } The file/line of the export'ed function is expected in the error message. Use it in error messages. panic: runtime error: cgo result is unpinned Go pointer or points to unpinned Go pointer goroutine 17 [running, locked to thread]: panic({0x7df72b1d8ae0?, 0x3ec8a1790030?}) /mnt/go/src/runtime/panic.go:877 +0x16f runtime.cgoCheckArg(0x7df72b1d62c0, 0x3ec8a16eee50, 0x68?, 0x0, {0x7df72b1ad44c, 0x42}) /mnt/go/src/runtime/cgocall.go:679 +0x35b runtime.cgoCheckResult({0x7df72b1d62c0, 0x3ec8a16eee50}) /mnt/go/src/runtime/cgocall.go:795 +0x4b _cgoexp_3c910ddb72c4_foo(0x7ffca1b21020) /mnt/tmp/parse.go:8 +0x5d runtime.cgocallbackg1(0x7df72b1a4360, 0x7ffca1b21020, 0x0) /mnt/go/src/runtime/cgocall.go:446 +0x289 runtime.cgocallbackg(0x7df72b1a4360, 0x7ffca1b21020, 0x0) /mnt/go/src/runtime/cgocall.go:350 +0x132 runtime.cgocallbackg(0x7df72b1a4360, 0x7ffca1b21020, 0x0) :1 +0x2b runtime.cgocallback(0x0, 0x0, 0x0) /mnt/go/src/runtime/asm_amd64.s:1101 +0xcd runtime.goexit({}) /mnt/go/src/runtime/asm_amd64.s:1712 +0x1 So doing, fix typos in comments. Link: https://web.archive.org/web/20251008114504/https://dave.cheney.net/2018/01/08/gos-hidden-pragmas Suggested-by: Keith Randall For #75856 Change-Id: I0bf36d5c8c5c0c7df13b00818bc4641009058979 GitHub-Last-Rev: e65839cfb2e28a879beac67c5c550de871b00018 GitHub-Pull-Request: golang/go#76118 Reviewed-on: https://go-review.googlesource.com/c/go/+/716441 Reviewed-by: Keith Randall Reviewed-by: Michael Pratt Auto-Submit: Michael Pratt Reviewed-by: Keith Randall Reviewed-by: Florian Lehner LUCI-TryBot-Result: Go LUCI --- src/cmd/cgo/main.go | 4 ++-- src/cmd/cgo/out.go | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/cmd/cgo/main.go b/src/cmd/cgo/main.go index 5e08427daf..955d64b956 100644 --- a/src/cmd/cgo/main.go +++ b/src/cmd/cgo/main.go @@ -72,8 +72,8 @@ type File struct { ExpFunc []*ExpFunc // exported functions for this file Name map[string]*Name // map from Go name to Name NamePos map[*Name]token.Pos // map from Name to position of the first reference - NoCallbacks map[string]bool // C function names that with #cgo nocallback directive - NoEscapes map[string]bool // C function names that with #cgo noescape directive + NoCallbacks map[string]bool // C function names with #cgo nocallback directive + NoEscapes map[string]bool // C function names with #cgo noescape directive Edit *edit.Buffer debugs []*debug // debug data from iterations of gccDebug. Initialized by File.loadDebug. diff --git a/src/cmd/cgo/out.go b/src/cmd/cgo/out.go index a2bcdf89c5..394e766d4e 100644 --- a/src/cmd/cgo/out.go +++ b/src/cmd/cgo/out.go @@ -1144,6 +1144,10 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) { if !p.hasPointer(nil, atype, false) { return } + + // Use the export'ed file/line in error messages. + pos := fset.Position(exp.Func.Pos()) + fmt.Fprintf(fgo2, "//line %s:%d\n", pos.Filename, pos.Line) fmt.Fprintf(fgo2, "\t_cgoCheckResult(a.r%d)\n", i) }) } -- 2.52.0