本文介绍了通过jni从C ++调用Java代码时出现奇怪的sigsegv的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码是漂亮的样板代码,可以按原样运行,但是在gdb中运行时会崩溃.因此,我不会在意这一点,但是这是我较大程序的简化版本,该程序在有或没有gdb的情况下也会崩溃.对于我在这里做错的任何帮助,将不胜感激.

Following code is pretty boiler plate code that runs fine as is, but when run in gdb crashes. As such I won't care about that, but this is reduced version of my bigger program which also crashes with or without gdb. Any help on what I'm doing wrong here would be tremendously appreciated.

它在对JVM的最后一次调用中崩溃"jobject hbase_configuration = env-> CallStaticObjectMethod(cls,create_mid);"

It crashes in in the very last call to JVM "jobject hbase_configuration = env->CallStaticObjectMethod(cls, create_mid);"

我曾尝试通过不同的方式通过JNI调用HBaseConfiguration.Create,并且在所有情况下均会崩溃. gdb上的堆栈跟踪似乎不太有用,尽管已使用-g进行了编译,但我无法从中获得任何符号.

I have tried calling HBaseConfiguration.Create many times through JNI through different things, and in all cases it crashes. The stack trace on gdb does not seem very helpful, I Can't get any symbols out of it, despite having compiled with -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 ?? ()

推荐答案

这确实是技术在注释中所建议的.由于jvm向SIVM抛出了SIGSEGV,因此gdb崩溃是一个红鲱鱼.

This was indeed what technomage had suggested in the comments. The gdb crash was a red herring because of jvm throwing SIGSEGV which was meant to be handled by jvm.

一旦我告诉gdb处理SIGSEGV nostop",它就可以正常工作,并且能够调试更大的程序.

Once I tell gdb "handle SIGSEGV nostop", it works just fine and I was able to debug my larger program.

这篇关于通过jni从C ++调用Java代码时出现奇怪的sigsegv的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-03 17:28