1

私は、JNI を介して Java 側から呼び出される、アプリケーションのネイティブ C ライブラリ部分でのクラッシュのデバッグに取り組んでいます。

Java が残してくれたクラッシュ ファイルの次の部分を見つけました。

# JRE version: 6.0_16-b01
# Java VM: Java HotSpot(TM) 64-Bit Server VM (14.2-b01 mixed mode linux-amd64 )
# Problematic frame:
# C  [binaryname.so+0x2760]  functionname+0x59

私はこれを逆コンパイルしました:

[richg@SVR-LRH-ES-2A]$ gdb binaryname.so
...
(gdb) disas 0x275e 0x2768
Dump of assembler code from 0x275e to 0x2768:
0x000000000000275e <functionname+87>:  rex.RB clc
0x0000000000002760 <functionname+89>:  movzbl 0x230(%rax),%eax
0x0000000000002767 <functionname+96>:  test   %al,%al

スタック トレースとレジスタ セクションをもう一度見ると、次のことがわかります。

RAX=0xffffffffffffffff, RBX=0x00002aab6cdf46c8, RCX=0x00002b70e0f15d73, RDX=0x000000005d5ffbe0
RSP=0x00000000463f9710, RBP=0x00000000463f9770, RSI=0x00002b70e0f27820, RDI=0x00000000463f9748
R8 =0x00002b70e0f27838, R9 =0x000000005cfa9828, R10=0x000000005cfa9478, R11=0x000000005cfa9440
R12=0x00002aab84654000, R13=0x00002aab6cdf46c8, R14=0x00000000463f9808, R15=0x00002aab84654000
RIP=0x00002aab79316760, EFL=0x0000000000010206, CSGSFS=0x0000000000000033, ERR=0x0000000000000004
TRAPNO=0x000000000000000e

したがって、%rax は 0xffffffffffffffff です。それは私には疑わしいように見えます。

とはいえ、x86 に関する知識は少し前に使い果たしました。私はmovzについていくつか読んだことがあり、それが何をするのか理解しています(下位24ビットをゼロでパディングすることにより、8ビット整数から32ビット整数にキャストします)が、まだ質問があります:

1) 呼び出しの 0x230 部分の意味は何ですか? コード内で別の番号を持つ movzbl の他の使用法を見ることができます。

2) 入力レジスタの値が 8 ビットより大きい場合 (ここでは %rax がそうです)、これはオーバーフローでクラッシュすると考えるのは正しいですか? (もしそうなら、これが私のクラッシュの根本的な原因になります。)

3) Java から提供されたレジスタ ダンプに %eax がないのはなぜですか?

4

1 に答える 1

1

0x230 はオフセットで、通常の世界を0x230(%rax)意味します。[rax+0x230]

というmovzbl 0x230(%rax),%eax意味になりmovzx eax, byte ptr [rax+0x230]ます。

ここには実際の入力レジスタはなくrax、アドレスを保持することになっています。-1 はアドレスとしてあまり有効ではないようです。それがおそらく問題です。

eaxはもちろんレジスタダンプにあります - の下半分を見てくださいrax

于 2012-07-20T16:11:36.963 に答える