[英]SIGSEGV: Segmentation Fault in JCC Library Code
I'm using the JCC Python-Java bridge and for the most part it works. 我正在使用JCC Python-Java桥,并且在大多数情况下都可以使用。 However, I'm getting the following error:
但是,出现以下错误:
JRE version: 7.0_17-b02
JRE版本:7.0_17-b02
Java VM: Java HotSpot(TM) Client VM (23.7-b01 mixed mode linux-x86 )
Java VM:Java HotSpot(TM)客户端VM(23.7-b01混合模式linux-x86)
Problematic frame:
有问题的框架:
C [_ciasliveschema.so+0x21e75c] boxJObject(_typeobject*, _object*, java::lang::Object*)+0x22c
C [_ciasliveschema.so + 0x21e75c] boxJObject(_typeobject *,_object *,java :: lang :: Object *)+ 0x22c
The stack dump is as follows: 堆栈转储如下:
Stack: [0xbfbe5000,0xbfc35000], sp=0xbfc33820, free space=314k
堆栈:[0xbfbe5000,0xbfc35000],sp = 0xbfc33820,可用空间= 314k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
本机框架:(J =编译的Java代码,j =解释的,Vv = VM代码,C =本机代码)
C [_ciasliveschema.so+0x21e75c] boxJObject(_typeobject*, _object*, java::lang::Object*)+0x22c
C [_ciasliveschema.so + 0x21e75c] boxJObject(_typeobject *,_object *,java :: lang :: Object *)+ 0x22c
C [_ciasliveschema.so+0x221977] boxObject(_typeobject*, _object*, java::lang::Object*)+0x27
C [_ciasliveschema.so + 0x221977] boxObject(_typeobject *,_ object *,java :: lang :: Object *)+ 0x27
C [_ciasliveschema.so+0x225149] _parseArgs(_object* , unsigned int, char , ...)+0x2f69
C [_ciasliveschema.so + 0x225149] _parseArgs(_object * ,unsigned int,char ,...)+ 0x2f69
C [_ciasliveschema.so+0x17e21c] schema::util::t_IndividualCaster_asMessage (schema::util::t_IndividualCaster*, _object*)+0xac
C [_ciasliveschema.so + 0x17e21c]模式:: util :: t_IndividualCaster_asMessage(schema :: util :: t_IndividualCaster *,_object *)+ 0xac
C [python+0x8bda4] PyEval_EvalFrameEx+0x6494
C [python + 0x8bda4] PyEval_EvalFrameEx + 0x6494
C [python+0x8ccb1] PyEval_EvalCodeEx+0x871
C [python + 0x8ccb1] PyEval_EvalCodeEx + 0x871
C [python+0xe0a0c] fileno@@GLIBC_2.0+0xe0a0c
C [python + 0xe0a0c] fileno @@ GLIBC_2.0 + 0xe0a0c
C [python+0x143b5] PyObject_Call+0x45
C [python + 0x143b5] PyObject_Call + 0x45
C [python+0x1b107] fileno@@GLIBC_2.0+0x1b107
C [python + 0x1b107] fileno @@ GLIBC_2.0 + 0x1b107
C [python+0x143b5] PyObject_Call+0x45
C [python + 0x143b5] PyObject_Call + 0x45
C [python+0x84a72] PyEval_CallObjectWithKeywords+0x42
C [python + 0x84a72] PyEval_CallObjectWithKeywords + 0x42
C [python+0x1eec1] PyInstance_New+0x71
C [python + 0x1eec1] PyInstance_New + 0x71
C [python+0x143b5] PyObject_Call+0x45
C [python + 0x143b5] PyObject_Call + 0x45
C [python+0x86923] PyEval_EvalFrameEx+0x1013
C [python + 0x86923] PyEval_EvalFrameEx + 0x1013
C [python+0x8b347] PyEval_EvalFrameEx+0x5a37
C [python + 0x8b347] PyEval_EvalFrameEx + 0x5a37
C [python+0x8ccb1] PyEval_EvalCodeEx+0x871
C [python + 0x8ccb1] PyEval_EvalCodeEx + 0x871
C [python+0x8cd47] PyEval_EvalCode+0x57
C [python + 0x8cd47] PyEval_EvalCode + 0x57
The code for the boxJObject function is as follows: boxJObject函数的代码如下:
static int boxJObject(PyTypeObject *type, PyObject *arg,
java::lang::Object *obj)
{
if (arg == Py_None)
{
if (obj != NULL)
*obj = Object(NULL);
}
else if (PyObject_TypeCheck(arg, &PY_TYPE(Object)))
{
if (type != NULL && !is_instance_of(arg, type))
return -1;
if (obj != NULL)
*obj = ((t_Object *) arg)->object;
}
else if (PyObject_TypeCheck(arg, &PY_TYPE(FinalizerProxy)))
{
arg = ((t_fp *) arg)->object;
if (PyObject_TypeCheck(arg, &PY_TYPE(Object)))
{
if (type != NULL && !is_instance_of(arg, type))
return -1;
if (obj != NULL)
*obj = ((t_Object *) arg)->object;
}
else
return -1;
}
else
return 1;
return 0;
}
This is called in the following manner: 可以通过以下方式调用它:
int result = boxJObject(type, arg, obj);
Also, I have modified the following section of the jcc.cpp:initVM() method: 此外,我还修改了jcc.cpp:initVM()方法的以下部分:
if (JNI_CreateJavaVM(&vm, (void **) &vm_env, &vm_args) < 0)
{
for (unsigned int i = 0; i < nOptions; i++)
delete vm_options[i].optionString;
PyErr_Format(PyExc_ValueError,
"An error occurred while creating Java VM");
return NULL;
}
As follows: 如下:
vm_args.nOptions = nOptions;
vm_args.ignoreUnrecognized = JNI_FALSE;
vm_args.options = vm_options;
vmInitSuccess = JNI_CreateJavaVM(&vm, (void **) &vm_env, &vm_args);
if (vmInitSuccess < 0)
{
for (unsigned int i = 0; i < nOptions; i++)
delete vm_options[i].optionString;
//Set up basic error message
sprintf(strVMInitSuccess, "%d", vmInitSuccess);
strcpy(strVMError, "An error occurred while creating Java VM (No Exception): ");
strcat(strVMError, strVMInitSuccess);
//Get exception if there is one
if((exc = vm_env->ExceptionOccurred()))
{
//Clear the exception since we have it now
vm_env->ExceptionClear();
//Get the getMessage() method
if ((java_class = vm_env->FindClass ("java/lang/Throwable")))
{
if ((method = vm_env->GetMethodID(java_class, "getMessage", "()Ljava/lang/String;")))
{
int size;
strExc = static_cast<jstring>(vm_env->CallObjectMethod(exc, method));
charExc = vm_env->GetStringUTFChars(strExc, NULL);
size = sizeof(strVMError) + sizeof(charExc);
char strVMException[size];
strcpy(strVMException, "An error occurred while creating Java VM (Exception): ");
strcat(strVMException, charExc);
PyErr_Format(PyExc_ValueError, strVMException);
return NULL;
}
}
}
PyErr_Format(PyExc_ValueError, strVMError);
return NULL;
}
This was to attempt to get a more detailed error message back from JCC when errors occur, so it is possible that this is the source of the error (although the segfault error and stack trace above suggest otherwise). 这是为了尝试在发生错误时从JCC处获得更详细的错误消息,因此这可能是错误的来源(尽管上面的segfault错误和堆栈跟踪另有建议)。
Finally, I am currently invoking the initVM() method from within Python as follows: 最后,我目前正在从Python内部调用initVM()方法,如下所示:
self.__cslschemalib = ciasliveschema.initVM(classpath=ciasliveschema.CLASSPATH)
However, when I attempt to invoke the method as follows (to increase the amount of memory available): 但是,当我尝试按以下方式调用该方法(以增加可用的内存量)时:
self.__cslschemalib = ciasliveschema.initVM(classpath=ciasliveschema.CLASSPATH, initialheap='512m', maxheap='2048m', maxstack='2048m', vmargs='-Xcheck:jni,-verbose:jni,-verbose:gc')
I get the following error: 我收到以下错误:
JRE version: 7.0_17-b02 Java VM: Java HotSpot(TM) Client VM (23.7-b01 mixed mode linux-x86 ) Problematic frame: C 0x00000000
JRE版本:7.0_17-b02 Java VM:Java HotSpot(TM)客户端VM(23.7-b01混合模式linux-x86)问题框架:C 0x00000000
And stack trace: 和堆栈跟踪:
Stack: [0xbf6e0000,0xbf8e0000], sp=0xbf8dd580, free space=2037k
堆栈:[0xbf6e0000,0xbf8e0000],sp = 0xbf8dd580,可用空间= 2037k
Any suggestions? 有什么建议么?
The problem has been resolved. 这个问题已经解决。 The problem actually arose in the call to the above boxJObject method:
该问题实际上是在对上述boxJObject方法的调用中出现的:
if (boxObject(NULL, arg, obj) < 0) return -1;
Which is the _parseArgs function in functions.cpp of the JCC source code. 这是JCC源代码的functions.cpp中的_parseArgs函数。
The problem arose because (at least from a quick scan of this function), _parseArgs checks to see whether more args have been passed than the method accepts, but does not check for the case in which fewer args have been passed. 之所以出现此问题,是因为(至少从对该函数的快速扫描开始),_parseArgs检查是否已传递了比该方法接受的更多的 arg,但没有检查已传递了更少的arg的情况。
In the call to the IndividualCaster().asMessage() method in my Python code I was passing just one argument when the method actually takes two. 在我的Python代码中对IndividualCaster()。asMessage()方法的调用中,当方法实际上需要两个参数时,我仅传递了一个参数。 While I haven't located the precise source of the error in the _parseArgs method, I have corrected the call in my Python code so that it now takes the correct number of args, and the seg fault is no longer occurring.
虽然我没有在_parseArgs方法中找到错误的确切来源,但我已经更正了我的Python代码中的调用,以便现在可以使用正确数量的args,并且不再发生seg错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.