我将CLion与c ++项目(cmake)一起使用,该项目启动了jvm。 Java部分是用gradle构建的。该项目有效,但是调试时遇到了问题。
启动JVM时,我立即获得了SIGSEGV。我了解这是正常现象,除了忽略SIGSEGV之外,没有其他解决方法。有点烦人,但还算不错,因为它每次会话只发生一次。
但是,此后,我继续进行调试,并获得恒定的SIGBUS信号。
<unknown> 0x000000011f108385
<unknown> 0x000000011761dca7
<unknown> 0x000000011761dca7
<unknown> 0x000000011761da00
<unknown> 0x000000011761da00
<unknown> 0x000000011761da00
<unknown> 0x000000011761da00
<unknown> 0x000000011761dae2
<unknown> 0x000000011761da00
<unknown> 0x000000011761dae2
<unknown> 0x000000011761da00
<unknown> 0x000000011761dae2
<unknown> 0x000000011761da00
<unknown> 0x0000000117614849
JavaCalls::call_helper(JavaValue*,methodHandle const&,JavaCallArguments*,Thread*) 0x000000010bf3a582
StackWalk::fetchFirstBatch(BaseFrameStream&,Handle,long,int,objArrayHandle,Thread*) 0x000000010c227cac
StackWalk::walk(Handle,Thread*) 0x000000010c2278fc
JVM_CallStackWalk 0x000000010bfb14a2
<unknown> 0x0000000117623950
<unknown> 0x000000011761da00
<unknown> 0x000000011761da00
<unknown> 0x000000011761da00
<unknown> 0x000000011761da00
<unknown> 0x000000011761da00
<unknown> 0x000000011761da00
<unknown> 0x000000011761da00
<unknown> 0x000000011761da00
<unknown> 0x000000011761dae2
<unknown> 0x000000011761da00
<unknown> 0x000000011761da00
<unknown> 0x0000000117614849
JavaCalls::call_helper(JavaValue*,Thread*) 0x000000010bf3a582
InstanceKlass::call_class_initializer(Thread*) 0x000000010bf22af7
InstanceKlass::initialize_impl(Thread*) 0x000000010bf2244f
Reflection::invoke_constructor(oopDesc*,Thread*) 0x000000010c1ebdbb
JVM_NewInstanceFromConstructor 0x000000010bfc14f6
<unknown> 0x0000000117623950
<unknown> 0x000000011761da00
<unknown> 0x000000011761da00
<unknown> 0x000000011761dae2
<unknown> 0x000000011761da00
<unknown> 0x000000011761da00
<unknown> 0x000000011761dae2
<unknown> 0x000000011761dae2
<unknown> 0x000000011761dcec
<unknown> 0x000000011761da00
<unknown> 0x000000011761da00
<unknown> 0x000000011761dae2
<unknown> 0x000000011761da00
<unknown> 0x000000011761da00
<unknown> 0x000000011761dae2
<unknown> 0x000000011761da00
<unknown> 0x000000011761da00
<unknown> 0x000000011761da00
<unknown> 0x000000011761da00
<unknown> 0x000000011761da00
<unknown> 0x000000011761da00
<unknown> 0x0000000117614849
JavaCalls::call_helper(JavaValue*,Thread*) 0x000000010bf3a582
jni_invoke_static(JNIEnv_*,JavaValue*,_jobject*,JNICallType,_jmethodID*,JNI_ArgumentPusher*,Thread*) 0x000000010bf7e2af
jni_CallStaticVoidMethodV 0x000000010bf81c69
JNIEnv_::CallStaticVoidMethod(_jclass*,...) jni.h:1521
main main.cpp:80
start 0x00007fff6f6563d5
start 0x00007fff6f6563d5
它不会在我的代码中停止。除了忽略所有SIGBUS,我不明白为什么会这样,或者是否有可能避免它们。
我最小化了代码,并创建了最简单的示例来重现该问题。基本上,我创建了一个cpp项目,该项目以 org / junit / platform / console / ConsoleLauncher 作为主要对象(junit5)启动了jni,它进行了一个简单的测试。 SIGBUS发生了。它发生在我的测试甚至没有运行之前。
我怀疑JUnit中有什么,但不确定。有什么办法可以找到根本原因?
用于复制的样本项目在这里:https://github.com/tallavi/sigbus-reproduction
如果我运行它,您会看到代码在调用Java部分之后停止运行,没有“之后调用”,没有“ CppMainEnd”:
CppMainStart
current_path: /Users/tal/Development/v2x/qa-automation/sigbus-reproduction/out
Loading JAR: jars/junit-platform-console-standalone-1.5.2.jar
Loading JAR: jars/.DS_Store
Loading JAR: jars/junit-platform-console-standalone-1.6.0-M1.jar
Loading JAR: jars/sigbus-reproduction.jar
CreateVM: JVM loaded successfully!
Before call
test START
test END
Thanks for using JUnit! Support its development at https://junit.org/sponsoring
.
+-- JUnit Jupiter [OK]
| '-- FirstTest [OK]
| '-- myTest() [OK]
'-- JUnit Vintage [OK]
Test run finished after 154 ms
[ 3 containers found ]
[ 0 containers skipped ]
[ 3 containers started ]
[ 0 containers aborted ]
[ 3 containers successful ]
[ 0 containers failed ]
[ 1 tests found ]
[ 0 tests skipped ]
[ 1 tests started ]
[ 0 tests aborted ]
[ 1 tests successful ]
[ 0 tests failed ]
Process finished with exit code 0
如果我只是将main从JUnit5更改为main并运行相同的代码,则一切正常:
CppMainStart
current_path: /Users/tal/Development/v2x/qa-automation/sigbus-reproduction/out
Loading JAR: jars/junit-platform-console-standalone-1.5.2.jar
Loading JAR: jars/.DS_Store
Loading JAR: jars/junit-platform-console-standalone-1.6.0-M1.jar
Loading JAR: jars/sigbus-reproduction.jar
CreateVM: JVM loaded successfully!
Before call
main START
main END
After call
CppMainEnd
Process finished with exit code 0
我通过@ Oo.oO的建议来管理信号,但这当然不能解决问题。 Java代码已完成,但是如果我尝试访问该JVM(例如销毁它),它将挂起! :
但是,如果我让它运行(而不是尝试对其进行调试),则会崩溃并显示其他错误:
main(31549,0x1177515c0) malloc: *** error for object 0x7ffee6360628: pointer being freed was not allocated
main(31549,0x1177515c0) malloc: *** set a breakpoint in malloc_error_break to debug
使用此跟踪:
请注意,并非总是会发生SIGBUS,但是JVM调用之后的代码会100%地停止运行。
希望这对任何人都有意义。
更新:这就是它在lldb中的样子:
MyComputer:out tal$ lldb main
(lldb) target create "main"
Current executable set to 'main' (x86_64).
(lldb) r
Process 57274 launched: '/Users/tal/Development/v2x/qa-automation/sigbus-reproduction/out/main' (x86_64)
CppMainStart
Process 57274 stopped
* thread #1,queue = 'com.apple.main-thread',stop reason = signal SIGSEGV
frame #0: 0x000000010b33f51b
-> 0x10b33f51b: movl (%rsi),%eax
0x10b33f51d: leaq 0x30(%rbp),%rsi
0x10b33f521: movl $0x10000,%eax ; imm = 0x10000
0x10b33f526: andl 0x4(%rsi),%eax
Target 0: (main) stopped.
(lldb) c
Process 57274 resuming
CreateVM: JVM loaded successfully!
Before call
Process 57274 stopped
* thread #1,stop reason = signal SIGBUS
frame #0: 0x0000000112e263ff
-> 0x112e263ff: testl %eax,(%r10)
0x112e26402: retq
0x112e26403: nop
0x112e26404: nop
Target 0: (main) stopped.
(lldb) c
Process 57274 resuming
test START
test END
Thanks for using JUnit! Support its development at https://junit.org/sponsoring
╷
├─ JUnit Jupiter ✔
│ └─ FirstTest ✔
│ └─ myTest() ✔
└─ JUnit Vintage ✔
Test run finished after 2740 ms
[ 3 containers found ]
[ 0 containers skipped ]
[ 3 containers started ]
[ 0 containers aborted ]
[ 3 containers successful ]
[ 0 containers failed ]
[ 1 tests found ]
[ 0 tests skipped ]
[ 1 tests started ]
[ 0 tests aborted ]
[ 1 tests successful ]
[ 0 tests failed ]
After call
before destroying
after destroying
CppMainEnd
Process 57274 exited with status = 0 (0x00000000)