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

signal arrived during external code execution #31

Open
oneym opened this issue Jul 8, 2020 · 12 comments
Open

signal arrived during external code execution #31

oneym opened this issue Jul 8, 2020 · 12 comments
Labels

Comments

@oneym
Copy link

oneym commented Jul 8, 2020

hi!
when i run example code in windows, get this

Exception 0xc0000005 0x0 0x0 0x3a903b6
PC=0x3a903b6
signal arrived during external code execution

github.com/timob/jnigi._Cfunc_dyn_JNI_CreateJavaVM(0x6b7f90, 0x6b7f70, 0x7a7f90, 0x0)
        _cgo_gotypes.go:2691 +0x54
github.com/timob/jnigi.jni_CreateJavaVM.func1(0x6b7f90, 0x6b7f70, 0x7a7f90, 0x519040)
        github.com/timob/jnigi/windows.go:42 +0xcb
github.com/timob/jnigi.jni_CreateJavaVM(0x6b7f90, 0x6b7f70, 0x7a7f90, 0xc000092030)
        github.com/timob/jnigi/windows.go:42 +0x46
github.com/timob/jnigi.CreateJVM(0xc000092030, 0x10006, 0xc00008ff20, 0x1, 0x1)
        github.com/timob/jnigi/jnigi.go:97 +0x7b
rax     0x6
rbx     0x4200800
rcx     0xcafebabe
rdi     0x1
rsi     0x0
rbp     0x511e9020
rsp     0x22f578
r8      0x3a9047b
r9      0x22f740
r10     0x2
r11     0x22f8b0
r12     0x3d8
r13     0x7
r14     0x6
r15     0x400
rip     0x3a903b6
rflags  0x210246
cs      0x33
fs      0x53
gs      0x2b
gosdk : go1.13.4
jdk : 
java version "1.8.0_152"
Java(TM) SE Runtime Environment (build 1.8.0_152-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.152-b16, mixed mode)
@timob
Copy link
Owner

timob commented Jul 10, 2020

Hi,

Are you talking about the exaple from the readme (https://github.com/timob/jnigi/blob/master/README.md#example)? If you are using Oracle JVM, you could try OpenJDK instead. Also you can try adding options to jnigi.NewJVMInitArgs to get the JVM to print out more debugging info.

@oneym
Copy link
Author

oneym commented Jul 17, 2020

Hi,
When I load a openjdk jvm.dll, I get the same massage like before.
My java version as below:

openjdk version "1.8.0_232-release"
OpenJDK Runtime Environment (build 1.8.0_232-release-1638-b6)
OpenJDK 64-Bit Server VM (build 25.232-b6, mixed mode)

@timob
Copy link
Owner

timob commented Jul 18, 2020

Can you post the code that causes this please?

@dbarganski
Copy link
Contributor

dbarganski commented Aug 12, 2020

Seems like I am affected in exactly same way on Windows. Same code on Linux target works.

Exception 0xc0000005 0x0 0x0 0x25ce5f60764
PC=0x25ce5f60764
signal arrived during external code execution

github.com/xxxx/jnigi._Cfunc_dyn_JNI_CreateJavaVM(0x25cb66d60c0, 0x25cb66d60a0, 0x25cb66d6020, 0x0)
        _cgo_gotypes.go:2708 +0x54

windows 10

java --version
openjdk 11.0.1 2018-10-16 LTS
OpenJDK Runtime Environment Zulu11.2+3 (build 11.0.1+13-LTS)
OpenJDK 64-Bit Server VM Zulu11.2+3 (build 11.0.1+13-LTS, mixed mode)

go version
go version go1.15 windows/amd64

gcc --version
gcc (tdm64-1) 9.2.0

@timob: As it may be version related. On which go/gcc/jvm version it's confirmed to work? I may try to downgrade and compile with these versions to rule out GO/GCC regression. Tried the usual workarounds with this exception but none of them worked out.

Init code is damn simple:


	var env *jnigi.Env
	var err error

	config.jvm, env, err = jnigi.CreateJVM(
		jnigi.NewJVMInitArgs(false, true, jnigi.JNI_VERSION_1_6,
			config.jvmOpts))
	if err != nil {
		log.Fatalln("CreateJVM error: ", err)
	}

@timob
Copy link
Owner

timob commented Aug 12, 2020

I am getting this as well. To fix you need to make a change to your Go install on Windows and recompile:

Here:
https://github.com/golang/go/blob/master/src/runtime/signal_windows.go#L172
So:

--- a/src/runtime/signal_windows.go
+++ b/src/runtime/signal_windows.go
@@ -169,7 +169,7 @@ func firstcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
        return _EXCEPTION_CONTINUE_EXECUTION
 }

-var testingWER bool
+var testingWER = true

 // lastcontinuehandler is reached, because runtime cannot handle
 // current exception. lastcontinuehandler will print crash info and exit.

This disables some of the Go exception handling.

There is an issue about exception handling in Go on Windows:
golang/go#20498

During CreateJavaJVM Java uses this exception handling for some reason.

I made that change and sucessfully ran go test. I am using go1.14.6 and openjdk version "1.8.0_212".

@dbarganski
Copy link
Contributor

Thank you I confirm provided runtime fix workarounds problem on windows. On the other side looked inside go and jvm internals and not absolutely sure it's really safe (I do not pretend to understand that low level) The funny things is windows jvm code path has exception wrapper( confirmed in jvm source and described here https://www.oracle.com/java/technologies/javase/signals.html). May it be incomplete go check here https://github.com/golang/go/blob/master/src/runtime/signal_windows.go#L66 ? As long as I understand go is configuring itself as vectored SEH which kicks-in before JVM exception handler and may explain why it panics unnecessarily. What I was looking for is a workaround without changing GO runtime. Having some problems with gdb so cannot confirm or reject the hypothesis.

@timob
Copy link
Owner

timob commented Apr 27, 2021

Can anyone test with https://go-review.googlesource.com/c/go/+/195577/ ? I might do this once I have time.

@ziyunhai
Copy link

Hi。I encountered the same problem。Can you help with the problem。

Exception 0xc0000005 0x0 0x0 0x177800003b6
PC=0x177800003b6
signal arrived during external code execution

runtime.cgocall(0xbd638d, 0xc000121ab8)
        C:/Software/gosdk/go1.17.6/src/runtime/cgocall.go:156 +0x4a fp=0xc000121a80 sp=0xc000121a48 pc=0xb0434a
demo/jnigi._Cfunc_dyn_JNI_CreateJavaVM(0x177d5695630, 0x177d5694980, 0x177d5692840)
        _cgo_gotypes.go:2876 +0x5a fp=0xc000121ab8 sp=0xc000121a80 pc=0xbc867a
demo/jnigi.jni_CreateJavaVM.func1(0x177d5695630, 0x177d5694980, 0x177d5692840)
        D:/workspace/workspace_go/jnigi_demo/src/demo/jnigi/windows.go:43 +0xc5 fp=0xc000121b20 sp=0xc000121ab8 pc=0xbce9e5
demo/jnigi.jni_CreateJavaVM(0x177d5695630, 0x177d5694980, 0x177d5692840)
        D:/workspace/workspace_go/jnigi_demo/src/demo/jnigi/windows.go:43 +0x3f fp=0xc000121b50 sp=0xc000121b20 pc=0xbce8df
demo/jnigi.CreateJVM(0xc000006030)
        D:/workspace/workspace_go/jnigi_demo/src/demo/jnigi/jnigi.go:171 +0x85 fp=0xc000121bf0 sp=0xc000121b50 pc=0xbb7aa5
main.main()
        D:/workspace/workspace_go/jnigi_demo/src/demo/main.go:19 +0x205 fp=0xc000121f80 sp=0xc000121bf0 pc=0xbcf865
runtime.main()
        C:/Software/gosdk/go1.17.6/src/runtime/proc.go:255 +0x1d7 fp=0xc000121fe0 sp=0xc000121f80 pc=0xb3a537
runtime.goexit()
        C:/Software/gosdk/go1.17.6/src/runtime/asm_amd64.s:1581 +0x1 fp=0xc000121fe8 sp=0xc000121fe0 pc=0xb626c1

goroutine 2 [force gc (idle)]:
runtime.gopark(0xc19b00, 0xca0ca0, 0x11, 0x14, 0x1)
        C:/Software/gosdk/go1.17.6/src/runtime/proc.go:366 +0xf2 fp=0xc000057f88 sp=0xc000057f58 pc=0xb3a932
runtime.goparkunlock(0x0, 0x0, 0x0, 0x0)
        C:/Software/gosdk/go1.17.6/src/runtime/proc.go:372 +0x2a fp=0xc000057fb8 sp=0xc000057f88 pc=0xb3a9ca
runtime.forcegchelper()
        C:/Software/gosdk/go1.17.6/src/runtime/proc.go:306 +0xa5 fp=0xc000057fe0 sp=0xc000057fb8 pc=0xb3a765
runtime.goexit()
        C:/Software/gosdk/go1.17.6/src/runtime/asm_amd64.s:1581 +0x1 fp=0xc000057fe8 sp=0xc000057fe0 pc=0xb626c1
created by runtime.init.7
        C:/Software/gosdk/go1.17.6/src/runtime/proc.go:294 +0x25

goroutine 3 [GC sweep wait]:
runtime.gopark(0xc19b00, 0xca0da0, 0xc, 0x14, 0x1)
        C:/Software/gosdk/go1.17.6/src/runtime/proc.go:366 +0xf2 fp=0xc000059f88 sp=0xc000059f58 pc=0xb3a932
runtime.goparkunlock(0x0, 0x0, 0x0, 0x0)
        C:/Software/gosdk/go1.17.6/src/runtime/proc.go:372 +0x2a fp=0xc000059fb8 sp=0xc000059f88 pc=0xb3a9ca
runtime.bgsweep()
        C:/Software/gosdk/go1.17.6/src/runtime/mgcsweep.go:163 +0x8f fp=0xc000059fe0 sp=0xc000059fb8 pc=0xb23d6f
runtime.goexit()
        C:/Software/gosdk/go1.17.6/src/runtime/asm_amd64.s:1581 +0x1 fp=0xc000059fe8 sp=0xc000059fe0 pc=0xb626c1
created by runtime.gcenable
        C:/Software/gosdk/go1.17.6/src/runtime/mgc.go:181 +0x55

goroutine 4 [GC scavenge wait]:
runtime.gopark(0xc19b00, 0xca0e00, 0xd, 0x14, 0x1)
        C:/Software/gosdk/go1.17.6/src/runtime/proc.go:366 +0xf2 fp=0xc000069f58 sp=0xc000069f28 pc=0xb3a932
runtime.goparkunlock(0x0, 0x0, 0x0, 0x0)
        C:/Software/gosdk/go1.17.6/src/runtime/proc.go:372 +0x2a fp=0xc000069f88 sp=0xc000069f58 pc=0xb3a9ca
runtime.bgscavenge()
        C:/Software/gosdk/go1.17.6/src/runtime/mgcscavenge.go:265 +0xd4 fp=0xc000069fe0 sp=0xc000069f88 pc=0xb21cf4
runtime.goexit()
        C:/Software/gosdk/go1.17.6/src/runtime/asm_amd64.s:1581 +0x1 fp=0xc000069fe8 sp=0xc000069fe0 pc=0xb626c1
created by runtime.gcenable
        C:/Software/gosdk/go1.17.6/src/runtime/mgc.go:182 +0x65

goroutine 5 [finalizer wait]:
runtime.gopark(0xc19b00, 0xcf6ad8, 0x10, 0x14, 0x1)
        C:/Software/gosdk/go1.17.6/src/runtime/proc.go:366 +0xf2 fp=0xc00005be00 sp=0xc00005bdd0 pc=0xb3a932
runtime.goparkunlock(0xc000054ea0, 0x80, 0x11, 0xc00005bf70)
        C:/Software/gosdk/go1.17.6/src/runtime/proc.go:372 +0x2a fp=0xc00005be30 sp=0xc00005be00 pc=0xb3a9ca
runtime.runfinq()
        C:/Software/gosdk/go1.17.6/src/runtime/mfinal.go:177 +0xab fp=0xc00005bfe0 sp=0xc00005be30 pc=0xb19f2b
runtime.goexit()
        C:/Software/gosdk/go1.17.6/src/runtime/asm_amd64.s:1581 +0x1 fp=0xc00005bfe8 sp=0xc00005bfe0 pc=0xb626c1
created by runtime.createfing
        C:/Software/gosdk/go1.17.6/src/runtime/mfinal.go:157 +0x45
rax     0x6
rbx     0xa100800
rcx     0xcafebabe
rdi     0x1
rsi     0x0
rbp     0x6572e4a0
rsp     0x6b4c5ff468
r8      0x1778000047b
r9      0x6b4c5ff630
r10     0x2
r11     0x6b4c5ff7a0
r12     0x3d8
r13     0x0
r14     0xc000054000
r15     0x20
rip     0x177800003b6
rflags  0x210246
cs      0x33
fs      0x53
gs      0x2b

go version
go version go1.16.4 windows/amd64

java version
java version "1.8.0_202"
Java(TM) SE Runtime Environment (build 1.8.0_202-b08)
Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)

@timob
Copy link
Owner

timob commented Aug 8, 2023

This is still a problem in version go1.21rc4. The problem is that OpenJDK DLL on windows uses SEH to trap exceptions, and then triggers exceptions on CreateJavaVM to test for OS bugs with exception handling, see https://stackoverflow.com/questions/36250235/exception-0xc0000005-from-jni-createjavavm-jvm-dll.

Go uses VEH on Windows and doesn't pass on exceptions to SEH, even on non go exceptions, it seems. There does seem to be code to handle this problem for a specific case on arm64 https://github.com/golang/go/blob/3393155abf77e460fe661ffccb0b21c500290613/src/runtime/signal_windows.go#L300.

Maybe we could propose the same for OpenJDK DLL:

	// OpenJDK JVM DLL uses SEH to trap segfaults during runtime
	// initialization to test for OS bugs related to signal handling.
	// On x86, non go exception, assume this and pass onward to SEH.
	if (GOARCH == "amd64" || GOARCH == "386") && info.exceptioncode == _EXCEPTION_ACCESS_VIOLATION &&
		(r.ip() < firstmoduledata.text || firstmoduledata.etext < r.ip()) {
		return _EXCEPTION_CONTINUE_SEARCH
	}

This means that Go exceptions would be handled in the normal way and non go exceptions would be handled by externally for segfaults.

@dbarganski
Copy link
Contributor

dbarganski commented Aug 8, 2023

Hello, I am using following workaround in production for the last couple of years on go1.17+ without known issues. Of course your case may be different.

Windows WER/Signal fix

WINWERFIX=sed -i -E 's/^(var testingWER bool).*$$/\1 = true/' $(GOROOT)/src/runtime/signal_windows.go

(Addendum)
Workaround is not available starting go1.21rc1 due to removal of testingWER in the following patch:
golang/go@65ea4c5

@timob
Copy link
Owner

timob commented Aug 8, 2023

This is really an issue with golang/go I just updated here first, might do a issue on golang/go sometime.

@yawuliu
Copy link

yawuliu commented Oct 25, 2024

Hello, I am using following workaround in production for the last couple of years on go1.17+ without known issues. Of course your case may be different.

Windows WER/Signal fix

WINWERFIX=sed -i -E 's/^(var testingWER bool).*$$/\1 = true/' $(GOROOT)/src/runtime/signal_windows.go

(Addendum) Workaround is not available starting go1.21rc1 due to removal of testingWER in the following patch: golang/go@65ea4c5

your workaround realy Inspired me.

package main

import (
	"java2go/jni"
	_ "unsafe"
)

//go:linkname testingWER runtime.testingWER
var testingWER bool

func main() {
	testingWER = true
	jni.JniFunc()
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants