Question

I'm using the JCC Python-Java bridge and for the most part it works. However, I'm getting 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 [_ciasliveschema.so+0x21e75c] boxJObject(_typeobject*, _object*, java::lang::Object*)+0x22c

The stack dump is as follows:

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] fileno@@GLIBC_2.0+0xe0a0c

C [python+0x143b5] PyObject_Call+0x45

C [python+0x1b107] fileno@@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

The code for the boxJObject function is as follows:

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:

    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).

Finally, I am currently invoking the initVM() method from within Python as follows:

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

And stack trace:

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

Any suggestions?

Était-ce utile?

La solution

The problem has been resolved. The problem actually arose in the call to the above boxJObject method:

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

Which is the _parseArgs function in functions.cpp of the JCC source code.

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.

In the call to the IndividualCaster().asMessage() method in my Python code I was passing just one argument when the method actually takes two. 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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top