Phi*_*vey 8 c++ java debugging java-native-interface coredump
我的应用程序主要是Java,但对于某些计算,它使用C++库.我们的环境是在RedHat 3上运行的Java 1.6(很快就是RedHat 5).
我的问题是C++库不是线程安全的.为了解决这个问题,我们运行多个单线程"工作"流程,并让他们从中央工作管理器开始工作,也是用C++编写的.我们的Java应用程序通过第三方产品调用C++ Work Manager.
出于各种原因,我们希望重新编写C++ Work Manager和worker.我赞成用Java编写它们,在每个worker中使用JNI来调用C++库.
主要问题是如果C++库核心转储会发生什么.不幸的是,这很常见,我们需要能够看到我们的C++库中的哪一行导致了这个问题,例如通过检查GDB之类的回溯.
我的同事认为,分析核心转储是不可能的,因为像GDB这样的工具不了解Java生成的核心文件.
我希望他们错了,但在进一步推动我的想法之前我需要确定.
分析Java/JNI生成的核心转储的最佳方法是什么?
小智 7
要将核心文件读入 gdb,您必须向其中添加 java 虚拟机。那是
gdb /usr/local/jdk1.8.0_66/bin/java core
Run Code Online (Sandbox Code Playgroud)
它很可能会告诉您未找到大量符号(这是正常的,这些是 JVM 符号)。但是,如果您键入“bt”,则崩溃的 JNI 调用可能会出现在您的堆栈跟踪中。一个例子,在我的情况下,我在我写的本地库中崩溃了,是:
(gdb) bt
#0 0x00007fd61dfcd107 in __GI_raise (sig=sig@entry=6)
at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1 0x00007fd61dfce4e8 in __GI_abort () at abort.c:89
#2 0x00007fd61d8d3795 in os::abort(bool) ()
from /usr/local/jdk1.8.0_66/jre/lib/amd64/server/libjvm.so
#3 0x00007fd61da71e23 in VMError::report_and_die() ()
from /usr/local/jdk1.8.0_66/jre/lib/amd64/server/libjvm.so
#4 0x00007fd61d8d8fbf in JVM_handle_linux_signal ()
from /usr/local/jdk1.8.0_66/jre/lib/amd64/server/libjvm.so
#5 0x00007fd61d8cf753 in signalHandler(int, siginfo*, void*) ()
from /usr/local/jdk1.8.0_66/jre/lib/amd64/server/libjvm.so
#6 <signal handler called>
Run Code Online (Sandbox Code Playgroud)
前 6 帧都与崩溃过程本身有关。一个信号被捕获并发送。虽然我们不知道确切的功能,但这并不重要。从第 7 帧开始,我们在我们编写的 JNI 库中。如果它仍然附有符号,您将看到它们。
#7 0x00007fd5ff43bf7e in FftResampler::resample(Complex const*, int)
()
from /I/home/werner/BpmDj/NextGen/Beta/Desktop/test/libzathras-46703-64.so
#8 0x00007fd5ff43ddcf in TimeStretcher::rescaleEnvelopeSlow(PeakMap const*, Peak*) ()
from /I/home/werner/BpmDj/NextGen/Beta/Desktop/test/libzathras-46703-64.so
#9 0x00007fd5ff43e4a5 in TimeStretcher::transferPeak(Frame*, Frame*)
()
from /I/home/werner/BpmDj/NextGen/Beta/Desktop/test/libzathras-46703-64.so
#10 0x00007fd5ff43e679 in TimeStretcher::transferPeaks(Channel*) ()
from /I/home/werner/BpmDj/NextGen/Beta/Desktop/test/libzathras-46703-64.so
#11 0x00007fd5ff43eb3a in TimeStretcher::putStereo(float const*, int)
()
from /I/home/werner/BpmDj/NextGen/Beta/Desktop/test/libzathras-46703-64.so
#12 0x00007fd5ff43edbf in TimeStretcher::processStereo(float const*, int, float*) ()
from /I/home/werner/BpmDj/NextGen/Beta/Desktop/test/libzathras-46703-64.so
#13 0x00007fd5ff43b45d in Java_org_yellowcouch_bpmdj_mixedit_audio_JavaTimeStretcher_processStereo ()
from /I/home/werner/BpmDj/NextGen/Beta/Desktop/test/libzathras-46703-64.so
Run Code Online (Sandbox Code Playgroud)
从第 14 帧开始,我们又回到了 Java 领域。
#14 0x00007fd6097a29e1 in ?? ()
#15 0x00007fd5d6ee6580 in ?? ()
#16 0x00000000853f53e8 in ?? ()
#17 0x00000000d803c340 in ?? ()
#18 0x00000000d80564e8 in ?? ()
#19 0x00007fd61e773609 in _L_unlock_554 ()
from /lib/x86_64-linux-gnu/libpthread.so.0
Run Code Online (Sandbox Code Playgroud)
所以你看到通过gdb从核心文件中获取一些信息并不是完全不可能的。只是不要忘记将 jvm 添加为它的第一个参数。
gdb 可能找不到本机库本身。在这种情况下,您可能希望手动加载符号,如下所示:
gdb> 符号文件 libzathras-46703-64.so
如果您需要更多信息,您可能需要在打开调试信息的情况下编译您的 c/c++ 代码。通常使用 mingw 和 gcc 编译器,您会在命令行选项中添加 -g。这将为您提供以下信息,其中包括行号等。
#7 FftResampler::resample (this=this@entry=0x7f4bf8f36100,
cpx=cpx@entry=0x7f4bf8ed1ea0, n=<optimized out>)
at timestretcher.cpp:347
#8 0x00007f4c51605dcf in TimeStretcher::rescaleEnvelopeSlow (
this=0x7f4bf8ec1e10, table=0x7f4bf90f4c20, borders=0x7f4bf8fd27a0)
at timestretcher.cpp:878
#9 0x00007f4c516064a5 in TimeStretcher::transferPeak (
this=this@entry=0x7f4bf8ec1e10,
prevFrame=prevFrame@entry=0x7f4bf8fde6f0,
frame=frame@entry=0x7f4bf8fb2650) at timestretcher.cpp:718
#10 0x00007f4c51606679 in TimeStretcher::transferPeaks (
this=this@entry=0x7f4bf8ec1e10,
channel=channel@entry=0x7f4bf8ec9e90) at timestretcher.cpp:687
#11 0x00007f4c51606b3a in TimeStretcher::putStereo (
this=this@entry=0x7f4bf8ec1e10, in=in@entry=0x7f4bf8eb9e00,
time=time@entry=-1395) at timestretcher.cpp:1483
#12 0x00007f4c51606dbf in TimeStretcher::processStereo (
this=this@entry=0x7f4bf8ec1e10, in=in@entry=0x7f4bf8eb9e00,
time=time@entry=-1395, out=0x7f4bf90f4c60)
at timestretcher.cpp:1567
#13 0x00007f4c5160345d in Java_org_yellowcouch_bpmdj_mixedit_audio_JavaTimeStretcher_processStereo (env=0x7f4bf90f71f8, obj=<optimized out>,
handle=139964275465728, in=0x7f4bed136468, inIdx=<optimized out>,
time=-1395, out=0x7f4bed136480) at timestretcher-jni.cpp:69
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8199 次 |
最近记录: |