Работа с C и Java через JNI, выполнение вызова SetObjectArrayElement и запуск теста для ответа на некоторые связанные вопросы GDB.
Вот вызов JNI, используемый в C.
(*env)->SetObjectArrayElement(env, objArray, (jsize)i, obj1);
Код вызвал ядро, и после разборки кода он показывает, что в команде mov происходит сбой.
Dump of assembler code for function jni_SetObjectArrayElement:
0x00002b514569f510 <+0>: push %rbp
0x00002b514569f511 <+1>: mov %rsp,%rbp
0x00002b514569f514 <+4>: push %r15
0x00002b514569f516 <+6>: mov %rsi,%r15
0x00002b514569f519 <+9>: push %r14
0x00002b514569f51b <+11>: mov %rdi,%r14
0x00002b514569f51e <+14>: push %r13
0x00002b514569f520 <+16>: mov %rcx,%r13
0x00002b514569f523 <+19>: push %r12
0x00002b514569f525 <+21>: mov %edx,%r12d
0x00002b514569f528 <+24>: push %rbx
0x00002b514569f529 <+25>: lea -0x258(%rdi),%rbx
0x00002b514569f530 <+32>: sub $0x48,%rsp
0x00002b514569f534 <+36>: mov %fs:0x28,%rax
0x00002b514569f53d <+45>: mov %rax,-0x38(%rbp)
0x00002b514569f541 <+49>: xor %eax,%eax
0x00002b514569f543 <+51>: mov 0x2e8(%rbx),%eax
0x00002b514569f549 <+57>: cmp $0xdeab,%eax
0x00002b514569f54e <+62>: je 0x2b514569f567 <jni_SetObjectArrayElement+87>
0x00002b514569f550 <+64>: mov 0x2e8(%rbx),%eax
0x00002b514569f556 <+70>: cmp $0xdeac,%eax
0x00002b514569f55b <+75>: je 0x2b514569f567 <jni_SetObjectArrayElement+87>
0x00002b514569f55d <+77>: mov %rbx,%rdi
0x00002b514569f560 <+80>: xor %ebx,%ebx
0x00002b514569f562 <+82>: callq 0x2b5145a740f0 <_ZN10JavaThread18block_if_vm_exitedEv>
0x00002b514569f567 <+87>: mov %rbx,%rdi
0x00002b514569f56a <+90>: callq 0x2b5145691bb0 <_ZN21ThreadStateTransition22transition_from_nativeEP10JavaThread15JavaThreadState.constprop.220>
0x00002b514569f56f <+95>: cmpq $0x0,0x8(%rbx)
0x00002b514569f574 <+100>: mov %rbx,-0x70(%rbp)
0x00002b514569f578 <+104>: movq $0x0,-0x68(%rbp)
0x00002b514569f580 <+112>: je 0x2b514569f58b <jni_SetObjectArrayElement+123>
0x00002b514569f582 <+114>: lea -0x70(%rbp),%rdi
0x00002b514569f586 <+118>: callq 0x2b514591bf90 <_ZN25WeakPreserveExceptionMark8preserveEv>
0x00002b514569f58b <+123>: nop
0x00002b514569f58c <+124>: test %r13,%r13
=> 0x00002b514569f58f <+127>: mov (%r15),%r14 <-----Fails here
0x00002b514569f592 <+130>: je 0x2b514569f700 <jni_SetObjectArrayElement+496>
0x00002b514569f598 <+136>: mov 0x0(%r13),%r13
0x00002b514569f59c <+140>: test %r12d,%r12d
0x00002b514569f59f <+143>: js 0x2b514569f638 <jni_SetObjectArrayElement+296>
0x00002b514569f5a5 <+149>: lea 0x928397(%rip),%rax # 0x2b5145fc7943
0x00002b514569f5ac <+156>: movzbl (%rax),%edx
Команда "info reg" показывает r15 как значение NULL.
(gdb) info reg
rax 0x2b5145afa808 47628061485064
rbx 0x2b54538d2800 47641179006976
rcx 0x2b5424000a30 47640381229616
rdx 0x2b5424018c30 47640381328432
rsi 0x0 0
rdi 0x2b54538d2800 47641179006976
rbp 0x2b51935ed890 0x2b51935ed890
rsp 0x2b51935ed820 0x2b51935ed820
r8 0xf497fc9c 4103601308
r9 0x2b51480606f8 47628100699896
r10 0x398 920
r11 0x206 518
r12 0x0 0
r13 0x2b5424000a30 47640381229616
r14 0x2b54538d2a58 47641179007576
r15 0x0 0 <---------NULL
rip 0x2b514569f58f 0x2b514569f58f <jni_SetObjectArrayElement+127>
eflags 0x206 [ PF IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
Основываясь только на предоставленной информации, как я могу определить, какой параметр на самом деле равен NULL?
"(* env) -> SetObjectArrayElement (env, objArray, (jsize) i, obj1) "вызов возвращает пустоту и передает 4 параметра.
Рассматривая код сборки для jni_SetObjectArrayElement, можно ли предположить, что первые 4 команды "mov" перемещают 4 параметра в регистры?
Что делает другая команда mov?
0x00002b514569f510 <+0>: push %rbp
0x00002b514569f511 <+1>: mov %rsp,%rbp <------Parameter env?
0x00002b514569f514 <+4>: push %r15
0x00002b514569f516 <+6>: mov %rsi,%r15 <------Parameter objArray?
0x00002b514569f519 <+9>: push %r14
0x00002b514569f51b <+11>: mov %rdi,%r14 <------Parameter i?
0x00002b514569f51e <+14>: push %r13
0x00002b514569f520 <+16>: mov %rcx,%r13 <------Parameter obj1?
0x00002b514569f523 <+19>: push %r12
0x00002b514569f525 <+21>: mov %edx,%r12d <----What is this one for?
0x00002b514569f528 <+24>: push %rbx
0x00002b514569f529 <+25>: lea -0x258(%rdi),%rbx
0x00002b514569f530 <+32>: sub $0x48,%rsp
Я запустил код в другом сценарии, и код сборки для jni_SetObjectArrayElement фактически показывает следующие 4 команды mov вместо 5, как показано выше.Почему это так?
Dump of assembler code for function jni_SetObjectArrayElement:
0x00002b1c85caa2d0 <+0>: push %rbp
0x00002b1c85caa2d1 <+1>: mov %rsp,%rbp
0x00002b1c85caa2d4 <+4>: push %r15
0x00002b1c85caa2d6 <+6>: mov %rsi,%r15
0x00002b1c85caa2d9 <+9>: push %r14
0x00002b1c85caa2db <+11>: mov %rdi,%r14
0x00002b1c85caa2de <+14>: push %r13
0x00002b1c85caa2e0 <+16>: mov %rcx,%r13
0x00002b1c85caa2e3 <+19>: push %r12
0x00002b1c85caa2e5 <+21>: movslq %edx,%r12
0x00002b1c85caa2e8 <+24>: push %rbx
Основываясь на комментариях ниже, я считаю, что это правильная ссылка ... может быть.
0x00002b514569f510 <+0>: push %rbp
0x00002b514569f511 <+1>: mov %rsp,%rbp
0x00002b514569f514 <+4>: push %r15
0x00002b514569f516 <+6>: mov %rsi,%r15 <------Parameter env?
0x00002b514569f519 <+9>: push %r14
0x00002b514569f51b <+11>: mov %rdi,%r14 <------Parameter objArray?
0x00002b514569f51e <+14>: push %r13
0x00002b514569f520 <+16>: mov %rcx,%r13 <------Parameter i?
0x00002b514569f523 <+19>: push %r12
0x00002b514569f525 <+21>: mov %edx,%r12d <----Parameter obj1 (address in low order bytes)
0x00002b514569f528 <+24>: push %rbx
0x00002b514569f529 <+25>: lea -0x258(%rdi),%rbx
0x00002b514569f530 <+32>: sub $0x48,%rsp