java调用C++库崩溃排查
问题:java通过JNI方式调用C++库文件,运行时崩溃
1.首先生成core文件/或者gdb attach到进程上
//不限制core文件大小
ulimit -c unlimited
//core文件带pid和进程名 core在当前目录
echo "core_%e_%p" > /proc/sys/kernel/core_pattern
2.gdb查看core文件崩溃位置,可以看到是什么原因导致的崩溃,但是看不见堆栈
具体使用:gdb -c core-java-2853 -e java
结果:
Program received signal SIGSEGV, Segmentation fault.
(gdb) bt
#0 0x00007f19191429cf in ?? ()
#1 0x00000007c5922548 in ?? ()
#2 0x00000000000000b2 in ?? ()
#3 0x0000000000000000 in ?? ()
2.1 若是C++库的崩溃,怎可以看见崩溃的堆栈,要是java的崩溃怎看不见调用栈。
java崩溃看不见堆栈的原因:gdb调试的是java,Java里面是不会包括你写的程序的符号表了(因为符号表存储在自己写的Java程序中)。因为在java中没有读取到符号表,函数名、变量名这些都是存储在符号表中的,没有了符号表函数名自然无法解析了。那为什么不直接用GDB调试自己写的java程序呢?因为java程序只能在jvm上跑,并不能被操作系统直接调用。
3.jstack调试core文件
具体使用: jstack /usr/local/jdk/jre/bin/java core-java-2853
或者 jstack java /opt/log/core-java-2853
类似:
Debugger attached successfully.
Server compiler detected.
JVM version is 24.80-b11
Deadlock Detection:
No deadlocks found.
Thread 23259: (state = BLOCKED)
......
Thread 4400: (state = IN_JAVA)
Error occurred during stack walking:
java.lang.NullPointerException
at sun.jvm.hotspot.tools.StackTrace.run(StackTrace.java:78)
at sun.jvm.hotspot.tools.StackTrace.run(StackTrace.java:45)
at sun.jvm.hotspot.tools.JStack.run(JStack.java:60)
at sun.jvm.hotspot.tools.Tool.start(Tool.java:221)
......
4.jstack 查看阻塞进程的堆栈
jstack -l pid
打印pid对应进程的堆栈
5.jstack 用法
SYNOPSIS
jstack [ option ] pid
jstack [ option ] executable core
jstack [ option ] [server-id@]remote-hostname-or-IP
PARAMETERS
pid 对应进程号
executable 生成core的java可执行文件
core core dump文件
OPTIONS
-F 当"jstack [-l] pid"没有响应时强制生成core
-l 详细打印java堆栈,包含锁相关的东西
-m 混合打印,同时打印java和c/c++堆栈
-h 帮助信息