从c ++到jni调用java代码时奇怪的sigsegv

时间:2012-10-30 04:33:17

标签: java-native-interface

以下代码是漂亮的锅炉板代码,运行良好,但在gdb崩溃时运行。因此我不会关心这一点,但这是我的更大程序的缩减版本,它也会在有或没有gdb的情况下崩溃。对我在这里做错的任何帮助都会非常感激。

它在最后一次调用JVM时崩溃了“jobject hbase_configuration = env-> CallStaticObjectMethod(cls,create_mid);”

我尝试过多次通过JNI调用HBaseConfiguration.Create,并且在所有情况下都崩溃了。 gdb上的堆栈跟踪似乎没有什么帮助,尽管使用-g进行了编译,但我无法从中获取任何符号。

#include <string>
#include <glog/logging.h>
#include <jni.h>
// (edit - this was hidden in the original post).

int main(int argc, char* argv[]) {
  JavaVM *jvm;
  JNIEnv *env;
  JavaVMInitArgs vm_args;
  JavaVMOption options[5];

  vm_args.nOptions = 5;
  vm_args.version = JNI_VERSION_1_6;
  vm_args.options = options;
  vm_args.ignoreUnrecognized = 1;


  JNI_GetDefaultJavaVMInitArgs(&vm_args);

  options[0].optionString = "-Djava.class.path=hbase-1.0-SNAPSHOT.jar:activation-1.1.jar:asm-3.1.jar:avro-1.7.1.cloudera.2.jar:commons-beanutils-1.7.0.jar:commons-beanutils-core-1.8.0.jar:commons-cli-1.2.jar:commons-codec-1.4.jar:commons-collections-3.2.1.jar:commons-configuration-1.6.jar:commons-daemon-1.0.3.jar:commons-digester-1.8.jar:commons-el-1.0.jar:commons-httpclient-3.1.jar:commons-io-2.1.jar:commons-lang-2.5.jar:commons-logging-1.1.1.jar:commons-math-2.1.jar:commons-net-3.1.jar:ftplet-api-1.0.0.jar:ftpserver-core-1.0.0.jar:ftpserver-deprecated-1.0.0-M2.jar:guava-11.0.2.jar:hadoop-annotations-2.0.0-cdh4.1.1.jar:hadoop-auth-2.0.0-cdh4.1.1.jar:hadoop-common-2.0.2-alpha.jar:hadoop-common-2.0.2-alpha-tests.jar:hadoop-hdfs-2.0.0-cdh4.1.1.jar:hadoop-test-2.0.0-mr1-cdh4.1.1.jar:hbase-0.92.1-cdh4.1.0.jar:hbase-0.92.1-cdh4.1.0-sources.jar:hbase-0.92.1-cdh4.1.0-tests.jar:high-scale-lib-1.1.1.jar:hsqldb-1.8.0.10.jar:jaxb-api-2.1.jar:jaxb-impl-2.2.3-1.jar:jersey-core-1.8.jar:jersey-json-1.8.jar:jersey-server-1.8.jar:jets3t-0.6.1.jar:jline-0.9.94.jar:jsch-0.1.42.jar:jsp-api-2.1.jar:jsr305-1.3.9.jar:junit-4.10.jar:kfs-0.3.jar:log4j-1.2.17.jar:metrics-core-2.1.2.jar:paranamer-2.3.jar:protobuf-java-2.4.1.jar:servlet-api-2.5.jar:tools.jar";
  options[1].optionString = "-verbose:jni";
  options[2].optionString = "-Xcheck:jni:pedantic,verbose";
  options[3].optionString = "-Xdebug";
  options[4].optionString = "-Xrunjdwp:transport=dt_socket,address=4242,server=y,suspend=n";
  vm_args.nOptions = 5;
  vm_args.version = JNI_VERSION_1_6;
  vm_args.options = options;
  vm_args.ignoreUnrecognized = 1;


  // Load and initialize a Java VM, return a JNI interface 
  // pointer in env.
  long result = JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args);
  if (result == JNI_ERR) {
    LOG(ERROR) << "Failed to create a JVM";
    return false;
  }

   jclass cls = env->FindClass("org/apache/hadoop/hbase/HBaseConfiguration");
  if (cls == NULL) {
    LOG(ERROR) << " Could not find class org/apache/hadoop/hbase/HBaseConfiguration";
    return false;
  }

  jmethodID create_mid = env->GetStaticMethodID(
      cls, "create", "()Lorg/apache/hadoop/conf/Configuration;");
  if (create_mid == NULL) {
    LOG(ERROR) << "Could not find static method create in HBaseConfiguration";
    return false;
  }

  LOG(INFO) << "Creating conf";
  jobject hbase_configuration = env->CallStaticObjectMethod(cls, create_mid);

  LOG(INFO) << "Created conf";
  return 0;
}

堆栈跟踪看起来像:

#0  0x00007ffff134a722 in ?? ()
#1  0x00007ffff12e8410 in ?? ()
#2  0x0000000700000000 in ?? ()
#3  0x00007fffffffd150 in ?? ()
#4  0x00007fffffffd108 in ?? ()
#5  0x000000000060e800 in ?? ()
#6  0x000000077fbcaa30 in ?? ()
#7  0x000000000000001b in ?? ()
#8  0x0000000000000000 in ?? ()

1 个答案:

答案 0 :(得分:3)

这确实是technomage在评论中提出的建议。 gdb崩溃是一个红色的鲱鱼,因为jvm抛出SIGSEGV,这意味着由jvm处理。

一旦我告诉gdb“处理SIGSEGV nostop”,它就可以正常工作了,我能够调试我的大型程序。