2011-02-18 2 views
1

J'écris une application Java, à partir de laquelle j'appelle (via une autre bibliothèque) les fonctions de la bibliothèque OCR Cuneiform. Malheureusement, j'ai un accident dans un endroit très étrange, et j'ai besoin des conseils de la communauté.La bibliothèque cunéiforme tombe en panne lorsqu'elle est appelée via le pont JNI

Le programme se bloque sur la première ligne de code RVERLINE_MarkLines(), appelée depuis RSL_SetImportData(), dans une toute première position de code (initialisation de la variable lti). J'ai vérifié toutes les variables passées dans gdb: elles ont toutes un sens et semblent être valides. Il semble que la pile soit corrompue, comme une tentative de remaniement des lignes source dans RVERLINE_MarkLines() sans aucun succès.

Le même code pour les mêmes données d'entrée fonctionne bien lorsqu'il est invoqué à partir du code C++ (CPP CLI → une bibliothèque → bibliothèque cunéiforme), mais casse lorsqu'il est appelé depuis JVM (JVM → une bibliothèque → bibliothèque cunéiforme).

Comme je suis débutant avec gdb, peut-être quelqu'un peut me donner un indice, comment puis-je trouver la raison de l'accident? Où regarder et quoi faire attention?

Merci beaucoup à l'avance.

trace de la pile:

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 

Informations complémentaires:

  • Plate-forme Linux x32
  • SUN JVM 1.6.0.22
  • GCC 4.4.5

Répondre

2

Votre apparence crash comme un cas typique d'épuisement de la pile. Lorsque vous appelez la bibliothèque à partir de C++, vous utilisez probablement le thread principal, qui a généralement au moins 8 Mo. Lorsque vous l'appelez depuis Java, vous l'appelez à partir d'un thread autre que main, qui peut avoir une pile beaucoup plus petite (par exemple, for Linux x32 default stack size is 320k - qui peut varier pour différentes plates-formes et différentes implémentations JVM).

Les commandes suivantes devraient vous permettre de confirmer le problème:

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

Vous verrez probablement que $esp des points dans la page inaccessible (garde) (qui a ---p autorisations). Si cela est correct, vous devez soit créer le thread qui utilise la bibliothèque OCR avec une plus grande pile, soit vous assurer que la bibliothèque n'est accessible qu'à partir du thread principal. Vous pouvez le faire en utilisant par exemple. -Xss1024K Argument JVM (définira la taille de la pile pour tous les threads) ou -XX:MainThreadStackSize=1024K (définira la taille de la pile uniquement pour le thread principal sur HP-UX JVM).

Par exemple, il est OK pour $esp valeur 0xb755a000 être dans ce segment de mémoire (a) rw autorisations:

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