2011-02-18 45 views
1

我在写一个Java应用程序,我从中调用Cuneiform OCR库中的函数(通过另一个库)。不幸的是,我在一个非常奇怪的地方遇到了崩溃,我需要社区的建议。当通过JNI桥调用楔形文库时会崩溃

程序在RVERLINE_MarkLines()的第一个代码行上崩溃,从RSL_SetImportData()调用,在第一个代码位置(初始化变量lti)。我已经检查了所有在gdb中传递的变量:它们都有意义,似乎是有效的。它看起来像堆栈被损坏,因为试图在RVERLINE_MarkLines()重新洗牌源代码行没有任何成功。

从C++代码(CPP CLI→某个库→楔形库)调用相同输入数据的相同代码工作正常,但在从JVM(JVM→某库→楔形库)调用时会中断。

因为我是新手gdb,也许有人可以给我一个提示,我怎么才能找出崩溃的原因?在哪里看,以及要注意什么?

非常感谢提前。

堆栈跟踪:

Program received signal SIGSEGV, Segmentation fault. 
[Switching to Thread 0xb7564b70 (LWP 416)] 
RVERLINE_MarkLines (hCComp=0xb28a2708, hCPage=0xb28a28d0) 
    at cuneiform-1.0.0.orig/cuneiform_src/Kern/rverline/src/root/vl_kern.cpp:120 
120    LinesTotalInfo lti = {0}; // Структура хранения линий 
(gdb) bt 
#0 RVERLINE_MarkLines (hCComp=0xb28a2708, hCPage=0xb28a28d0) 
    at cuneiform-1.0.0.orig/cuneiform_src/Kern/rverline/src/root/vl_kern.cpp:120 
#1 0xb3b7d727 in RSL_SetImportData (dwType=1, pData=0xb7559b50) 
    at cuneiform-1.0.0.orig/cuneiform_src/Kern/rshelllines/src/rshelllines.cpp:332 
#2 0xb3bdca96 in RLINE_LinesPass1 (hCPage=0xb28a28d0, hCCOM=0xb28a2708, phCLINE=0xb45a34fc, pgneed_clean_line=0xb45a3630, sdl=0, 
    lang=0 '\000') at cuneiform-1.0.0.orig/cuneiform_src/Kern/rline/sources/newline.cpp:224 
#3 0xb3b70bb2 in SearchNewLines (Image=0xb7559e1c) 
    at cuneiform-1.0.0.orig/cuneiform_src/Kern/rstuff/sources/main/normalise.cpp:230 
#4 0xb3b70d78 in Normalise (Image=0xb7559e1c) 
    at cuneiform-1.0.0.orig/cuneiform_src/Kern/rstuff/sources/main/normalise.cpp:189 
#5 0xb3b6d900 in RSTUFF_RSNormalise (Image=0xb7559e1c, vBuff=0xb31ba008, Size=500000, vWork=0xb318e008, SizeWork=180000) 
    at cuneiform-1.0.0.orig/cuneiform_src/Kern/rstuff/sources/main/dll.cpp:352 
#6 0xb458919a in Layout (lpdata=0x0) at cuneiform-1.0.0.orig/cuneiform_src/Kern/puma/c/partlayout.cpp:203 
#7 0xb458b963 in PUMA_XFinalRecognition() at cuneiform-1.0.0.orig/cuneiform_src/Kern/puma/main/puma.cpp:590 
... 
#20 0xb77d5d0c in jni_CallStaticVoidMethod() from /usr/lib/jvm/java-6-sun-1.6.0.22/jre/lib/i386/client/libjvm.so 
#21 0x08049b98 in JavaMain() 
#22 0xb7fc3955 in start_thread (arg=0xb7564b70) at pthread_create.c:300 
#23 0xb7f35e7e in clone() at ../sysdeps/unix/sysv/linux/i386/clone.S:130 

附加信息:

  • 平台的Linux X32
  • SUN JVM 1.6.0.22
  • GCC 4.4.5

回答

2

你崩溃外观就像堆栈耗尽的典型案例。

当你从C++调用库时,你可能使用主线程,它通常至少有8MB。从Java调用它时,可以从main以外的某个线程调用它,该线程可能具有更小的堆栈(例如,for Linux x32 default stack size is 320k - 对于不同的平台和不同的JVM实现可能会有所不同)。

下面的命令应该让你确认问题:

(gdb) p/x $esp 
(gdb) shell cat /proc/<pid>/maps # replace <pid> with the pid of crashing 
            # thread, e.g. 416 above. 

您可能会看到$esp点到人迹罕至(后卫)页(其中有---p权限)。如果这是正确的,则必须创建使用更大堆栈的OCR库的线程,或者确保只能从主线程访问库。您可以通过使用例如-Xss1024K JVM参数(将设置所有线程的堆栈大小)或-XX:MainThreadStackSize=1024K(将仅为HP-UX JVM设置主线程的堆栈大小)。

例如它是确定用于$esp0xb755a000是这个存储器段内(具有rw权限):

b7517000-b7565000 rwxp 00000000 00:00 0   [threadstack:0004d494]