[带有Option 在结构内的奇怪内存布局

问题描述 投票:0回答:1

我正在使用here中的JNI定义。我创建了一个JNINativeInterface_,其中大多数成员都初始化为None。然后,我运行使用上述结构的RegisterNatives字段的本机代码。我这样初始化了RegisterNatives和周围的字段:

SetDoubleArrayRegion: unsafe { transmute(0xdeadbeaf as u64) },
RegisterNatives: Some(register_natives),
UnregisterNatives: unsafe { transmute(0xdeadbeaf as u64) },

register_natives的定义如下(这完全匹配库类型):

unsafe extern "system" fn register_natives(env: *mut sys::JNIEnv,
                                           clazz: jclass,
                                           methods: *const JNINativeMethod,
                                           nMethods: jint) -> jint {
    unimplemented!()
}

使用结构segfaults的本机代码(并且似乎获得了一个空ptr而不是register_natives)。

结构的相关部分在GDB中看起来像这样:

0x7ffcf5f4a5b8: 0x0 0x0 0x0 0x0
0x7ffcf5f4a5c8: 0xdeadbeaf  0x0 0x43fd9950  0x55ea
0x7ffcf5f4a5d8: 0xdeadbeaf  0x0 0x0 0x0
0x7ffcf5f4a5e8: 0x0 0x0 0x0 0x0

由于我一直期待0xdeadbeaf,其次是64位指针,然后是0xdeadbeaf,所以我对所要查看的内容感到困惑,但是正如您所见,这并不是我所得到的。关于在幕后将如何表示期权的假设,我是否错了?为什么bindgen /前述库似乎让Option产生了兼容的接口?

c struct rust java-native-interface unsafe
1个回答
0
投票

[...]我期望的是0xdeadbeaf,然后是64位指针,然后是0xdeadbeaf,但是正如您所见,这不是我所得到的。

我们一定不能看到同一件事,因为我do看到了。

0x7ffcf5f4a5c8: 0xdeadbeaf  0x0 0x43fd9950  0x55ea
0x7ffcf5f4a5d8: 0xdeadbeaf  0x0 0x0 0x0

每个十六进制数字都是32位整数,因此您必须将其中两个取为64位整数。第一个是0x00000000deadbeaf,第二个是0x000055ea43fd9950(大概是register_natives函数),第三个是0x00000000deadbeaf。 (从地址上也“很明显”:一个64位整数占用8个字节,因此需要两个来占用0x10字节。因此,每行有两个64位整数。)

程序出现段错误的原因可能是因为让外来代码引起恐慌的原因是undefined behavior。尝试将register_natives功能更改为不会引起惊慌的内容。

© www.soinside.com 2019 - 2024. All rights reserved.