Странное расположение памяти с Option в структуре - PullRequest
3 голосов
/ 18 января 2020

Я использую определения 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 приведет к совместимому интерфейсу?

1 Ответ

2 голосов
/ 18 января 2020

[...] Я ожидал 0xdeadbeaf, за которым следовал 64-битный указатель, затем 0xdeadbeaf, но, как вы видите, это не то, что я получаю.

Мы должны не вижу того же самого, потому что я делаю вижу это.

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

Каждое шестнадцатеричное число представляет собой 32-разрядное целое число, поэтому вам нужно взять два из них, чтобы получить 64 -битное целое число Первый - 0x00000000 deadbeaf, второй - 0x000055ea43fd9950 (предположительно, ваша register_natives функция), а третий - 0x00000000 deadbeaf снова. (Это также «очевидно» из адресов: 64-разрядное целое число занимает 8 байтов, поэтому для получения 0x10 байтов требуется два. Поэтому в каждой строке есть два 64-разрядных целых числа.)

Причина, по которой Возможные ошибки в программе могут быть вызваны тем, что разрешение развернуть pani c через сторонний код неопределенное поведение . Попробуйте изменить функцию register_natives на что-то, что не паникует c.

...