-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
cmd/cgo: signal arrived during external code execution that calls setjmp on Windows #13672
Comments
Looks a lot like #9754. Any chance you can write a standalone test case that does not involve using Lua? |
I assumed the OP meant this code: package main will panic on windows. I tried to reproduce it on windows/amd64, external linking works, C:\go\src>..\bin\go run -ldflags "-linkmode internal" x.go main._Cfunc_Print() goroutine 17 [syscall, locked to thread]: rax 0x459466 I'm not convinced that we need to fix internal linking as external linking |
If I'm reading this right, the problem is that cmd/link is not generating the correct exception information for the Windows OS. Is that correct? |
Does setjmp/longjmp require exception information?
The code doesn't actually raise any exception, it
basically, setjmp and then immediately longjmp.
|
It seems pretty clear from the error message that some exception is occurring. This MSDN page implies that longjmp is exception aware: https://msdn.microsoft.com/en-us/library/yz2ez4as.aspx . |
The problem turns out to be incorrect relocation by the internal linker.
mingw gcc generates a wrapper for longjmp.
objdump -d _all.o has this:
0000000000000076 <longjmp>:
76: 48 8d 05 00 00 00 00 lea 0x0(%rip),%rax # 7d
<longjmp+0x7>
79: R_X86_64_PC32 __imp_longjmp
7d: ff 20 jmpq *(%rax)
7f: 90 nop
But the final linked executable contains code like this:
0000000000459436 <longjmp>:
459436: 48 8d 05 f9 ff ff ff lea -0x7(%rip),%rax # 459436
<longjmp>
45943d: ff 20 jmpq *(%rax)
45943f: 90
Which is obviously incorrect.
|
cmd/link/internal/amd64/asm.go seems to want to reject this case:
But this only applies to the symbols that the linker knows are being imported. I believe here the generated .o file has inside it a reference to __imp_longjmp, and the linker knows nothing about that, and in particular does not have it marked as SDYNIMPORT, so no error is produced. I don't believe the linker is set up to handle this case. It's not just a trivial fix. Given that, we should probably leave this for Go 1.7. |
I did some debuging here:
and I get this output
Note that _all.o .text section has two interesting pe relocations: 3 and 4. 3 has symindex=53 which points to symbol
that points to small longjmp function in .text. While 4 has symindex=68 which points to symbol
which is just a place for external function (longjmp that gcc hoping to find in msvcrt.dll). You can also see those relocations converted into "go relocations". But "go relocatoins" 3 and 4 points to the same symbol. And this symbol settings match neither original longjmp nor __imp_longjmp settings. So I am not surprised that linker generates invalid code here. I think this is all to do with symbol renaming we do in readpesym. Alex |
I'm experiencing the same issue with the external linker - I was able to reproduce the issue as redstorm described it: when It's a bit tough to follow here: are there any leads on why externally linked binaries would still have this issue? |
@redstorm-fyy If this is still impacting you, I was able to work around it by using |
I am on When I call db.Close() (I verified there is an open connection) I get the following:
|
/cc @aclements |
@BorisKozo, it's not obvious to me that your crash involves setjmp/longjmp. Do you have evidence that it does? Basically anything going wrong in C code will cause "signal arrived during external code execution", and the exception code you got (0xc0000005, access violation) is different from the original report (0xc0000028, bad stack). Based on the exception code you got, it looks like the SQLite3 C code attempted to jump to a bad program counter (0xaa92f8). |
@aclements No evidence whatsoever. This is the first time I am doing something with CGo so I am not sure how to read those error messages or what they mean. |
@bradfitz package main func main(){ |
Nothing changed since #13672 (comment) This works with external linker, but broken with internal linker.
I doubt many people use internal linker nowadays. Alex |
Reopening because the problem still exists. |
Would this also be happening when using a DLL built with Visual Studio via the Syscall package? I believe I'm having similar symptoms. |
The problem discussed in this issue can only happens with Go program that uses Cgo. If your program does not uses Cgo, it cannot have this problem. Alex |
Here is an example of what appears to be this same issue happening in a recent PR to GoCV: https://ci.appveyor.com/project/deadprogram/gocv/build/216#L141 This code works as expected on Linux, but fails same test on Windows using Go 1.9.2, seemingly for attempting to catch the exception: |
@deadprogram I suspect that that problem you mention is actually #12516. Doesn't help much as that one is not fixed either. |
Hi @ianlancetaylor thanks for the tip. I will try out and exception handler that does not allocate any new memory and see if that helps. |
2 years and still no fix? |
Sorry, I could reproduce it. |
|
I get the same error message (signal arrived during external code execution) when running the tracking sample. Processor : Intel(R) Core(TM) i5-1035G1 CPU @ 1.00GHz 1.19 GHz When I verify the installation of gocv by runing the example cmd\version\main.go While when i try to run the example in cmd\hello\main.go who is supposed to open a video capture device using device “0”, read Exception 0x20474343 0x1e75b12bef0 0x64945198 0x7ffcd8744ed9 gocv.io/x/gocv._Cfunc_Window_IMShow(0x1e75b126a60, 0x1e75b12bce0) I'd like to add that I tried to run the same code in python with opencv (same camera id = 0 ) and it works well. |
I've dug a little bit into this. The problem seems to be that on Windows, This is a
If my diagnostic is accurate, I might be able to fix this issue as part of #57302. |
Processor Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz
OS: Windows 7 64
golang:1.5.2
gcc:mingw-w64 version 5.2.0 x86_64-posix-seh-rt_v4-rev1
When I compile golang with some external c code which using the setjmp and longjmp,the program crash.
My c code is here (It's in a c file in a directory which implements package lua)
My go code
Important!
It crashes when the c code is in an external file.When the c code is just up the .go file's import "C",It does not crash.
Crash information
Exception 0xc0000028 0x0 0x0 0x77b096f8
PC=0x77b096f8
signal arrived during external code execution
github.com/redstorm-fyy/go-lua/lua._Cfunc_Print()
??:0 +0x38
github.com/redstorm-fyy/go-lua/lua.Print()
E:/GolangRoot/src/github.com/redstorm-fyy/go-lua/lua/luago.go:587 +0x1b
main.main()
E:/GolangRoot/src/github.com/redstorm-fyy/go-lua/example/exam.go:6 +0x1b
goroutine 17 [syscall, locked to thread]:
runtime.goexit()
c:/go/src/runtime/asm_amd64.s:1721 +0x1
rax 0xf
rbx 0xc0000028
rcx 0x22ebd0
rdi 0x22c000
rsi 0x22f7b0
rbp 0x22f230
rsp 0x22eb10
r8 0x0
r9 0x400000
r10 0x0
r11 0x22f330
r12 0x22fe60
r13 0x22fdb0
r14 0x4013e8
r15 0x584024
rip 0x77b096f8
rflags 0x202
cs 0x33
fs 0x53
gs 0x2b
The text was updated successfully, but these errors were encountered: