你正在使用哪个版本的Go( go version
)?
$ go version
go version go1.20.8 windows/amd64
这个问题在最新版本中是否会重现?
不会。当使用相同的C工具链构建时,cgo测试套件(已移动到包路径 cmd/cgo/internal/test
)在Go 1.21中通过。
你正在使用什么操作系统和处理器架构( go env
)?
go env
输出
$ go env
set GO111MODULE=
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\ContainerAdministrator\AppData\Local\go-build
set GOENV=C:\Users\ContainerAdministrator\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=C:\go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=C:\Program Files\Go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=C:\Program Files\Go\pkg\tool\windows_amd64
set GOVCS=
set GOVERSION=go1.20.8
set GCCGO=gccgo
set GOAMD64=v1
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=C:\Program Files\Go\misc\go.mod
set GOWORK=
set CGO_CFLAGS=-O2 -g
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-O2 -g
set CGO_FFLAGS=-O2 -g
set CGO_LDFLAGS=-O2 -g
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=C:\Users\ContainerAdministrator\AppData\Local\Temp\go-build3913134811=/tmp/go-build -gno-record-gcc-switches
你做了什么?
C:\> docker run --rm -it golang:1.20.8 powershell
PS C:\go> $ProgressPreference='SilentlyContinue'
PS C:\go> Invoke-WebRequest https://github.com/brechtsanders/winlibs_mingw/releases/download/13.2.0-16.0.6-11.0.0-ucrt-r1/winlibs-x86_64-posix-seh-gcc-13.2.0-mingw-w64ucrt-11.0.0-r1.zip -OutFile winlibs-ucrt.zip
PS C:\go> Expand-Archive -Path .\winlibs-ucrt.zip -DestinationPath c:\tools
PS C:\go> $Env:PATH+='C:\tools\mingw64\bin'
PS C:\go> gcc --version
gcc.exe (MinGW-W64 x86_64-ucrt-posix-seh, built by Brecht Sanders) 13.2.0
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
PS C:\go> cd $(go env GOROOT)
PS C:\Program Files\Go> cd .\misc\cgo\test\
PS C:\Program Files\Go\misc\cgo\test> go test -ldflags=-linkmode=internal -tags=internal
你期望看到什么?
ok misc/cgo/test 3.869s
你看到了什么?
exit status 0xc0000409
FAIL misc/cgo/test 2.822s
go test -v
PS C:\Program Files\Go\misc\cgo\test> go test -v -ldflags=-linkmode=internal -tags=internal
=== RUN Test1328
--- PASS: Test1328 (0.00s)
=== RUN Test1560
--- PASS: Test1560 (0.00s)
=== RUN Test1635
scatter = 00000000008522E0
--- PASS: Test1635 (0.00s)
=== RUN Test3250
test.go:1277: not applicable on windows
--- SKIP: Test3250 (0.00s)
=== RUN Test3729
test.go:1353: skipping on windows
--- SKIP: Test3729 (0.00s)
=== RUN Test3775
--- PASS: Test3775 (0.00s)
=== RUN Test4029
--- PASS: Test4029 (0.00s)
=== RUN Test4339
--- PASS: Test4339 (0.00s)
=== RUN Test5227
--- PASS: Test5227 (0.00s)
=== RUN Test5242
--- PASS: Test5242 (0.00s)
=== RUN Test5337
--- PASS: Test5337 (0.00s)
=== RUN Test5548
--- PASS: Test5548 (0.00s)
=== RUN Test5603
--- PASS: Test5603 (0.00s)
=== RUN Test5986
sqrt is: 0
--- PASS: Test5986 (0.00s)
=== RUN Test6390
--- PASS: Test6390 (0.00s)
=== RUN Test6833
--- PASS: Test6833 (0.00s)
=== RUN Test6907
--- PASS: Test6907 (0.00s)
=== RUN Test6907Go
--- PASS: Test6907Go (0.00s)
=== RUN Test7560
--- PASS: Test7560 (0.00s)
=== RUN Test7665
--- PASS: Test7665 (0.00s)
=== RUN Test7978
--- PASS: Test7978 (0.67s)
=== RUN Test8092
--- PASS: Test8092 (0.00s)
=== RUN Test8517
--- PASS: Test8517 (0.00s)
=== RUN Test8694
--- PASS: Test8694 (0.00s)
=== RUN Test8756
--- PASS: Test8756 (0.00s)
=== RUN Test8811
--- PASS: Test8811 (0.00s)
=== RUN Test9026
--- PASS: Test9026 (0.00s)
=== RUN Test9510
--- PASS: Test9510 (0.00s)
=== RUN Test9557
--- PASS: Test9557 (0.00s)
=== RUN Test10303
--- PASS: Test10303 (0.00s)
=== RUN Test11925
--- PASS: Test11925 (0.00s)
=== RUN Test12030
--- PASS: Test12030 (0.00s)
=== RUN Test14838
--- PASS: Test14838 (0.00s)
=== RUN Test17065
--- PASS: Test17065 (0.00s)
=== RUN Test17537
--- PASS: Test17537 (0.00s)
=== RUN Test18126
--- PASS: Test18126 (0.00s)
=== RUN Test18720
--- PASS: Test18720 (0.00s)
=== RUN Test20129
--- PASS: Test20129 (0.00s)
=== RUN Test20266
--- PASS: Test20266 (0.00s)
=== RUN Test20369
--- PASS: Test20369 (0.00s)
=== RUN Test20910
--- PASS: Test20910 (0.00s)
=== RUN Test21708
--- PASS: Test21708 (0.00s)
=== RUN Test21809
--- PASS: Test21809 (0.00s)
=== RUN Test21897
issue21897b.go:13: test runs only on darwin+cgo
--- SKIP: Test21897 (0.00s)
=== RUN Test22906
--- PASS: Test22906 (0.00s)
=== RUN Test23356
--- PASS: Test23356 (0.00s)
=== RUN Test24206
test.go:2028: skipping on windows/amd64
--- SKIP: Test24206 (0.00s)
=== RUN Test25143
--- PASS: Test25143 (0.00s)
=== RUN Test26066
--- PASS: Test26066 (0.00s)
=== RUN Test26213
--- PASS: Test26213 (0.00s)
=== RUN Test27660
--- PASS: Test27660 (0.63s)
=== RUN Test28896
--- PASS: Test28896 (0.00s)
=== RUN Test30065
--- PASS: Test30065 (0.00s)
=== RUN Test32579
--- PASS: Test32579 (0.00s)
=== RUN Test31891
--- PASS: Test31891 (0.00s)
=== RUN Test42018
--- PASS: Test42018 (0.00s)
=== RUN Test45451
--- PASS: Test45451 (0.00s)
=== RUN Test49633
--- PASS: Test49633 (0.00s)
=== RUN TestAlign
--- PASS: TestAlign (0.00s)
=== RUN TestAtol
--- PASS: TestAtol (0.00s)
=== RUN TestBlocking
--- PASS: TestBlocking (0.00s)
=== RUN TestBoolAlign
--- PASS: TestBoolAlign (0.00s)
=== RUN TestCallGoWithString
--- PASS: TestCallGoWithString (0.00s)
=== RUN TestCallback
--- PASS: TestCallback (0.00s)
=== RUN TestCallbackCallers
--- PASS: TestCallbackCallers (0.00s)
=== RUN TestCallbackGC
--- PASS: TestCallbackGC (0.00s)
=== RUN TestCallbackPanic
--- PASS: TestCallbackPanic (0.00s)
=== RUN TestCallbackPanicLocked
--- PASS: TestCallbackPanicLocked (0.00s)
=== RUN TestCallbackPanicLoop
--- PASS: TestCallbackPanicLoop (0.36s)
=== RUN TestCallbackStack
--- PASS: TestCallbackStack (0.01s)
=== RUN TestCflags
--- PASS: TestCflags (0.00s)
=== RUN TestCheckConst
--- PASS: TestCheckConst (0.00s)
=== RUN TestConst
--- PASS: TestConst (0.00s)
=== RUN TestCthread
--- PASS: TestCthread (0.00s)
=== RUN TestEnum
--- PASS: TestEnum (0.00s)
=== RUN TestNamedEnum
--- PASS: TestNamedEnum (0.00s)
=== RUN TestCastToEnum
--- PASS: TestCastToEnum (0.00s)
=== RUN TestErrno
--- PASS: TestErrno (0.00s)
=== RUN TestFpVar
--- PASS: TestFpVar (0.00s)
=== RUN TestGCC68255
--- PASS: TestGCC68255 (0.00s)
=== RUN TestHandle
--- PASS: TestHandle (0.00s)
=== RUN TestHelpers
--- PASS: TestHelpers (0.00s)
=== RUN TestLibgcc
--- PASS: TestLibgcc (0.00s)
=== RUN TestMultipleAssign
exit status 0xc0000409
FAIL misc/cgo/test 3.012s
gdb
会话
PS C:\Program Files\Go\misc\cgo\test> go test -ldflags=-linkmode=internal -tags=internal -c
PS C:\Program Files\Go\misc\cgo\test> gdb -iex 'set auto-load safe-path /' test.test.exe
GNU gdb (GDB for MinGW-W64 x86_64, built by Brecht Sanders) 13.2
Copyright (C) 2023 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.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-w64-mingw32".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from test.test.exe...
Loading Go Runtime support.
(gdb) r -test.run TestMultipleAssign
Starting program: C:\Program Files\Go\misc\cgo\test\test.test.exe -test.run TestMultipleAssign
[New Thread 6928.0x21b4]
[New Thread 6928.0x1828]
[New Thread 6928.0x7f8]
[New Thread 6928.0x1188]
[New Thread 6928.0x1624]
[New Thread 6928.0x21e0]
[New Thread 6928.0x17c0]
gdb: unknown target exception 0xc0000409 at 0x7ffad467b3a8
Thread 1 received signal ?, Unknown signal.
0x00007ffad467b3a8 in ucrtbase!_invoke_watson () from C:\Windows\System32\ucrtbase.dll
(gdb) bt
#0 0x00007ffad467b3a8 in ucrtbase!_invoke_watson () from C:\Windows\System32\ucrtbase.dll
#1 0x00007ffad4660854 in ucrtbase!log2f () from C:\Windows\System32\ucrtbase.dll
#2 0x00007ffad4652e20 in ucrtbase!.intrinsic_setjmpex () from C:\Windows\System32\ucrtbase.dll
#3 0x00007ffad461ff0c in ucrtbase!strtol () from C:\Windows\System32\ucrtbase.dll
#4 0x0000000000c03822 in _cgo_0b47cc75cb3f_Cfunc_strtol ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
当使用相同MinGW-W64工具链的MSVCRT运行时变体时,cgo测试套件可以通过 -linkmode=internal
。
这个问题的影响最小。对于需要 to match up C runtime versions for compatibility with third-party DLLs 的人来说,外部链接是一个可行的解决方法。而对于我们这些从源代码构建Go并需要通过 go tool dist test
的人来说,切换到在构建Go工具链时链接到MSVCRT的MinGW是一个可行的解决方法,因为在Go 1.20的二进制分发中不需要预编译的本机代码。
3条答案
按热度按时间sdnqo3pr1#
我可以在提示中重现这个问题:
pod7payv2#
这是一个较小的复制器:
攻击者是
C.strtol(p, nil, 37)
。基本参数(37
)无效,因此strtol
尝试返回一个EINVAL
错误。我的当前理论是,当EINVAL
发生时,Windows执行一些依赖于栈正确且可展开的安全检查,但在这里并非如此,因为Go内部链接器没有将C编译器生成的SEH信息复制到最终的二进制文件中。由于安全检查未通过,程序崩溃。请注意,windows/amd64自 #57302 起支持SEH解包,但我在实现时错过了这个情况。
bqucvtff3#
我已经修复了CL 534555中的内部链接SEH问题,但
TestMultipleAssign
仍然失败。我会继续调查其他原因。