运行JNI本机代码时的JRE SIGSEGV

时间:2011-09-19 01:41:22

标签: java java-native-interface sigsegv

我需要通过JNI接口在Java对象和外部OCaml程序之间传输数据,但是我在访问本机代码中的对象字段时遇到了麻烦。

在Java方面,我有一个包含几个字段的类:

public class GPSState {

        int fix;
        double course;
        double hmsl;
        ...
}

我正在将jstate类的对象GPSState传递给C部分,我正在尝试将其字段设置为外部程序提供的各个值,这些值保存在本地结构中state

jclass cls;
jfieldID fid;

cls = (*env)->GetObjectClass( env, jstate);

fid = (*env)->GetFieldID( env, cls, "fix", "I");
(*env)->SetIntField( env, cls, fid, state.fix);

fid = (*env)->GetFieldID( env, cls, "course", "D");
(*env)->SetDoubleField( env, cls, fid, state.course); 

fid = (*env)->GetFieldID( env, cls, "hmsl", "D");
(*env)->SetDoubleField( env, cls, fid, state.hmsl);

...

从调试打印我已经知道该类已成功定位,并且fixcourse字段已正确识别和设置。但是在SetDoubleField字段上执行course调用后,紧接在调用行之后的调试打印确认后,当我尝试访问任何其他字段时,我总是收到SIGSEGV致命错误:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x01109720, pid=11665, tid=3079347056
#

后来我发现,当我将操作course字段的代码移动到设置字段的C函数的最末端时,错误消失并且所有字段都按预期设置而没有任何问题。

我尝试在另一台机器上使用另一个JRE实现运行代码,但结果是相同的,除了在设置第一个fix字段后出现错误(将代码的相应位移动到功能结束“再次解决”问题。)

现在,我知道我在某种程度上弄乱了记忆,但我无法弄清楚在哪里和如何。我按照JNI程序员指南中的字段和方法章节来检查可能的错误,但在我看来,我在书中做了所有事情。更有经验的人是否会如此友善并指出问题可能出在哪里?

1 个答案:

答案 0 :(得分:2)

(*env)->SetIntField( env, cls, fid, state.fix);

这看起来不对。您正在尝试设置对象实例字段,但是您要传递cls而不是jstate作为要访问的对象。您应该使用以下代码:

(*env)->SetIntField( env, jstate, fid, state.fix);

同时对其他Set<type>Field来电进行相应的更改。