2013-05-09 56 views
0

我正在使用JCC Python-Java橋接器,並且大部分工作正常。不過,我發現了以下錯誤:SIGSEGV:JCC庫代碼中的分段錯誤

JRE version: 7.0_17-b02

Java VM: Java HotSpot(TM) Client VM (23.7-b01 mixed mode linux-x86)

Problematic frame:

C [_ciasliveschema.so+0x21e75c] boxJObject(_typeobject*, _object*, java::lang::Object*)+0x22c

堆棧轉儲如下:

Stack: [0xbfbe5000,0xbfc35000], sp=0xbfc33820, free space=314k

Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)

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+0x225149] _parseArgs(_object*, unsigned int, char, ...)+0x2f69

C [_ciasliveschema.so+0x17e21c] schema::util::t_IndividualCaster_asMessage (schema::util::t_IndividualCaster*, _object*)+0xac

C [python+0x8bda4] PyEval_EvalFrameEx+0x6494

C [python+0x8ccb1] PyEval_EvalCodeEx+0x871

C [python+0xe0a0c] [email protected]@GLIBC_2.0+0xe0a0c

C [python+0x143b5] PyObject_Call+0x45

C [python+0x1b107] [email protected]@GLIBC_2.0+0x1b107

C [python+0x143b5] PyObject_Call+0x45

C [python+0x84a72] PyEval_CallObjectWithKeywords+0x42

C [python+0x1eec1] PyInstance_New+0x71

C [python+0x143b5] PyObject_Call+0x45

C [python+0x86923] PyEval_EvalFrameEx+0x1013

C [python+0x8b347] PyEval_EvalFrameEx+0x5a37

C [python+0x8ccb1] PyEval_EvalCodeEx+0x871

C [python+0x8cd47] PyEval_EvalCode+0x57

爲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; 
} 

這是按以下方式調用:

int result = boxJObject(type, arg, obj); 

另外,我已修改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; 
    } 

如下:

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; 
    } 

這是爲了試圖獲得更詳細的錯誤消息從背面JCC發生錯誤時,可能這是錯誤的根源(儘管上面的段錯誤和堆棧跟蹤表明了其他情況)。

最後,我目前從調用內Python中initVM()方法,如下所示:

self.__cslschemalib = ciasliveschema.initVM(classpath=ciasliveschema.CLASSPATH) 

然而,當我試圖調用的方法如下(以增加可用的存儲器的量):

self.__cslschemalib = ciasliveschema.initVM(classpath=ciasliveschema.CLASSPATH, initialheap='512m', maxheap='2048m', maxstack='2048m', vmargs='-Xcheck:jni,-verbose:jni,-verbose:gc') 

我得到以下錯誤:

JRE version: 7.0_17-b02 Java VM: Java HotSpot(TM) Client VM (23.7-b01 mixed mode linux-x86) Problematic frame: C 0x00000000

和堆棧跟蹤:

Stack: [0xbf6e0000,0xbf8e0000], sp=0xbf8dd580, free space=2037k

有什麼建議嗎?

回答

0

問題已解決。這個問題實際上出現在調用上述boxJObject方法:

if (boxObject(NULL, arg, obj) < 0) return -1; 

這是在JCC源代碼functions.cpp的_parseArgs功能。

問題的出現是因爲(從這個功能的快速掃描最小),_parseArgs檢查,看看 ARGS是否已經經過了比方法接受,但不檢查中較少ARGS一直的情況下通過。

在我的Python代碼中對IndividualCaster()。asMessage()方法的調用中,當方法實際需要兩個參數時,我只傳遞一個參數。儘管我沒有在_parseArgs方法中找到錯誤的確切來源,但我已經在我的Python代碼中更正了調用,因此它現在需要正確數量的參數,並且seg故障不再發生。