Antoine Sauray
Antoine Sauray

Reputation: 241

Segmentation fault on C++ destructor called from Jni

I am working on a research project to build a library which provides image processing tools. I need it to be wrapped from C++ to other languages.

I am currently working on the Java implementation using Jni (Java Native Interface).

My C++ core is built with a singleton pattern. Java calls C++ to get a pointer to the singleton.

static Kernel *getInstance()
    {
        if (!m_kernel)
            m_kernel = new Kernel;
        return m_kernel;
    }

C++ returns the pointer as a long value.

    JNIEXPORT jlong JNICALL Java_JavaCore_openKernelInstance(JNIEnv *, jobject)
{
    Kernel* kernel=Kernel::getInstance();
    std::cout << "pointer value at open" << kernel << std::endl;
    return long(kernel);
}

Java provides this value in every method that requires access to this object, to tell C++ where the object is located (It no longer holds the pointer).

Result

pointer address hex 10x7f0a440e3a20
pointer adress dec 139682068183584
id session1=0
id session2=1

Everything works fine except for the end of the "session". When Java asks C++ to close its work and delete its objects, here is what happends

pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
pointer delete0x7f9aa40d3660
Segmentation fault (core dumped)

There is an infinite loop where it tries to delete the pointer. Here is the destructor

Kernel::~Kernel(){
std::cout << "pointer delete" << m_kernel << std::endl;
delete m_kernel;

}

The java code

public static void main(String[] args){
    JavaCore jc = new JavaCore();
    long l = jc.openKernelInstance();
    int idSession = jc.openSession(l);
    int idSession2 = jc.openSession(l);
    System.out.println("pointer dec="+l);
    System.out.println("id session1="+idSession);
    System.out.println("id session2="+idSession2);
    jc.closeKernelInstance(l);
}

Upvotes: 0

Views: 531

Answers (1)

nogard
nogard

Reputation: 9716

This happens because you delete m_kernel object recursively in the destructor. Every time you call delete m_kernel you call the same destructor. You should not delete m_kernel in the destructor, it's enough to call delete once on the object: something like this.

void closeKernelInstance() {
    delete m_kernel;
}

And destructor should be empty in this case:

Kernel::~Kernel(){
}    

By the way, you could consider using Meyer's singleton, in this case your singleton will be destroyed automatically on exit:

static Kernel & getInstance()
{
    static Kernel theInstance;
    return theInstance;
}

Upvotes: 4

Related Questions