Cuneiform библиотека падает при вызове через мост JNI - PullRequest
1 голос
/ 18 февраля 2011

Я пишу Java-приложение, из которого я вызываю (через другую библиотеку) функции из Cuneiform OCR.К сожалению, у меня происходит сбой в очень странном месте, и мне нужен совет сообщества.

Программа вылетает в первой строке кода RVERLINE_MarkLines(), вызванной из RSL_SetImportData(), в самой первой позиции кода (инициализация переменной lti).Я проверил все переданные переменные в gdb: все они имеют смысл и кажутся действительными.Похоже, что стек поврежден, поскольку попытка перестановки исходных строк в RVERLINE_MarkLines() безуспешно.

Тот же код для тех же самых входных данных работает нормально, когда вызывается из кода C ++ (CPP CLI → someбиблиотека → библиотека клинописи), но прерывается при вызове из 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

1 Ответ

2 голосов
/ 19 февраля 2011

Ваш сбой выглядит как типичный случай исчерпания стека.

Когда вы вызываете библиотеку из C ++, вы, вероятно, используете основной поток, который обычно имеет не менее 8 МБ. Когда вы вызываете его из Java, вы вызываете его из другого потока, отличного от основного, который может иметь намного меньший стек (например, для Linux x32 размер стека по умолчанию равен 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 ).

Например, допустимо, чтобы $esp значение 0xb755a000 находилось в этом сегменте памяти (имеет разрешения rw):

b7517000-b7565000 rwxp 00000000 00:00 0          [threadstack:0004d494]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...