0

I am trying to run a simple C code that calls a Jar file and runs 3 methods from within it. (main, powerMethod, rootMethod) these functions call a C++ shared object. The Jar was already compiled with the .so and runs without errors when used through a Java program.

I am currently getting a Segmentation fault(core dumped) error when trying to run the C file. compilation is run without any errors.

compilation line:

 gcc -o run java_calls.c -I/usr/lib/jvm/java-16-oracle/include/linux -I/usr/lib/jvm/java-16-oracle/include -L/usr/lib/jvm/java-8-openjdk-arm64/jre/lib/aarch64/server -ljvm

I tried to debug the error and compiled again with the -g tag and then ran gdb run core and got the following error:

Starting program: /home/user/Desktop/JavaFromC/run 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x0000007fb75072b4 in ?? () from /usr/lib/jvm/java-1.8.0-openjdk-arm64/jre/lib/aarch64/server/libjvm.so

C program:

#include <jni.h>
#include <stdlib.h>
#include <stdio.h>

JNIEnv* create_jvm(JavaVM **java)
{
    JNIEnv *env;
    JavaVMInitArgs vm_args;
    JavaVMOption options;
    int res;

    vm_args.version = JNI_VERSION_1_8;
    vm_args.nOptions = 1;
    vm_args.options = &options;
    vm_args.ignoreUnrecognized = 0;
    options.optionString = "-Djava.class.path=./JavaC.jar";
    
    res = JNI_CreateJavaVM(java, (void**)&env, &vm_args);

    if(res < 0 || !env) {
        printf("Failed to create Java VM\n");
    } else {
        printf("JVM Created\n");
    }

    return env;

}
int main(int argc, char *argv[])
{
    JavaVM *jvm;
    JNIEnv *env;

    jclass java_c;
    jmethodID main_method;
    jmethodID power_method;
    jmethodID root_method;

    env = create_jvm(&jvm);

    if(env == NULL) {
        exit(1);
    }

    java_cp = (*env)->FindClass(env, "JavaC");
    if(java_cp == NULL) {
        printf("Failed to find JavaC class\n");
        return 1;
    }

    main_method = (*env)->GetStaticMethodID(env, java_c, "main", "([Ljava/lang/String;)V");
    if(main_method == NULL) {
        printf("Failed to find main function\n");
        return 1;
    }

    power_method = (*env)->GetStaticMethodID(env, java_c, "powerMethod", "(I)I");
    if(power_method == NULL) {
        printf("Failed to find power function\n");
        return 1;
    }
    root_method = (*env)->GetStaticMethodID(env, java_c, "rootMethod", "(D)D");
    if(root_method == NULL) {
        printf("Failed to find root function\n");
        return 1;
    }

    jint a_num = 12;
    jdouble b_num = 225;

    (*env)->CallStaticVoidMethod(env, java_c, main_method, NULL);
    printf("power = %d\n", (*env)->CallStaticIntMethod(env, java_c, power_method, a_num));
    printf("root = %f\n", (*env)->CallStaticDoubleMethod(env, java_c, root_method, b_num));

    return 0;
}
Ludwig12
  • 11
  • 3

1 Answers1

0

This answer may be relevant here. The SIGSEGV inside libjvm.so is "normal".

What you need to do is continue executing the program (by sending it SGISEGV with signal SIGSEGV GDB command) and letting it handle the signal, until you receive SIGSEGV that is not coming from libjvm.so.

Then you would know where the actual fatal SIGSEGV is coming from, and why. If you still don't understand the reason for it, you would need to update your question (edit it) with newly-observed info (output from info locals, backtrace, etc.) and a better answer may be given.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362