调试JVM崩溃(如何在底层C代码中找到错误?)

时间:2015-02-19 16:20:50

标签: java c raspberry-pi swig

运行一些SWIG生成的JNI代码时,我收到以下崩溃报告。

hs_er_pid4665.log

我怀疑C代码做的很顽皮,因为我可以看到C方法show导致问题;

# Problematic frame:
# C  [libws2812-RPi.so+0x4d84]  show+0x308

但我不确定如何进一步追求它。

C代码与{JNI github一起位于SWIG generated Java classes

我正在使用SWIG 2.0.7并编译所有内容;

swig -java -package bad.robot.unicorn.neopixel ws2812-RPi.i

gcc -fPIC -c ws2812-RPi.c ws2812-RPi_wrap.c -DPERI_BASE=0x3F000000 -DRPI2 -I/usr/lib/jvm/jdk-8-oracle-arm-vfp-hflt/include -I/usr/lib/jvm/jdk-8-oracle-arm-vfp-hflt/include/linux

gcc -shared ws2812-RPi.o ws2812-RPi_wrap.o -o libws2812-RPi.so

感谢kjp我创建了一个核心转储并运行gdp java core然后where提供了以下内容?它有助于诊断吗?

(gdb) where
#0  0x76dae8dc in raise () from /lib/arm-linux-gnueabihf/libc.so.6
#1  0x76db265c in abort () from /lib/arm-linux-gnueabihf/libc.so.6
#2  0x1b005d0a in ?? ()
#3  0x1b005d0a in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

您能从错误报告中看到问题所在吗?

2 个答案:

答案 0 :(得分:1)

你是对的,C代码正在做一些顽皮的事情。它可能由于某些无效的内存访问而导致SIGSEGV。 但是如果没有核心文件,调试C进程的内容并不容易。因此,启用核心转储,如下面的调试日志中所述:

ulimit -c unlimited

还可以通过添加-g标志在C编译上启用调试模式。 然后再次运行该过程并尝试使用gdb进行调试。

答案 1 :(得分:0)

分段错误意味着程序正在尝试访问它不应该访问的内存,并且崩溃报告确实似乎暗示了您的本机库。虽然您可以重新配置环境以启用核心转储,但如果您不准备对转储进行排序,那么这并不能让您走得太远。

为本机库编写自动化测试具有更大的长期价值。一个好的测试套件不仅可以帮助您查明这个特定的错误,它还可以帮助您捕获在维护和开发它时可能在库中出现的任何未来错误。当然,如果你的库有任何重要的大小并且还没有足够的测试,那么编写一个全面的测试套件将会有很多工作。