2

Android 1.6 エミュレーターでシンボルのないプログラムをデバッグしています。SO ライブラリのロード中にクラッシュ (シグナル) が発生しました。追跡しようとしています。クラッシュは、ライブラリの起動コードのどこかにあります。それはよくわかっています。制御がローダーから SO に移る前に、SO ローダー コード内の安全な場所を知っています。そこにブレークポイントを設定し、BLX からライブラリに至るまでステップを踏むことができます。ローダーのコードは Thumb です。ライブラリの起動コードは ARM です。

シンボルがないのでset arm force-mode xxx、GDB に知らせるために使用します。ローダーでの停止につながるシーケンスを開始する前に、モードを Thumb に設定します。

ただし、問題は、BLX命令に到達してシングルステップ ( si) を実行しようとすると、デバッガが次の命令で停止せず、シグナルまで進んでしまうことです。BLXで実行するset arm force-mode arm前に実行しsiても問題ないようです。

ライブラリの起動コードにブレークポイントを設定しても役に立ちません。GDB がブレークポイントを設定する正確な方法はわかりませんが、現在実行中のコードのモードと意図したブレークポイントのターゲット モードとの不一致が障害になっているようです。

編集:実行中のコードにモンキー パッチを適用して、適切な場所に BKPT コマンドを配置しようとしましたが、GDB はまだ壊れません。

EDIT2: コード セクションにモンキー パッチを適用しても機能しないようです。ただし、データ セクションの一部をスクラッチ領域として使用できます。それでも、BKPT によって GDB が壊れることはありません...


EDIT3: 3 行のコード スニペットにスクラッチ データ領域を使用すると、Thumb から切り替えてシグナルで GDB に戻ることができます。ただし、ARMモードになったので、GDBは何らかの理由でブレークポイントを設定できません。

BLX into library コマンドは次のようになりますblx r2。r2 の値は 0x80601b60 です。これはライブラリの起動ルーチンです。

BLX で停止した場合は、次のようにします。データ セクションにスクラッチ領域があります。そこに次の ARM コマンドを配置します。

mov r12, 0 ; the value of r12 will be soon ruined by the code anyway
ldr r12, [r12] ; Provoke a SIGSEGV to stop GDB in ARM mode
mov pc, r2 ; To resume back into the library

次に、強制的に r2 の値をスクラッチ領域に設定し、GDB モードを ARM に設定して続行します。スクラッチ領域の SIGSEGV は自然にスローされます。

ここでは、ARM モード (CPU と GDB の両方の強制モード) にいます。ライブラリのエントリ ポイントである 0x80601b60 にブレークポイントを設定しました。r2 の値を 0x80601b60 に戻して、3 番目のコマンドがそこにジャンプするようにします。r12 の値を有効な読み取りアドレスに変更して、再試行時にシグナルが再スローされないようにします。そしてsignal 0、信号なしで続行するようにコマンドを発行します。

コントロールが 0x80601b60 に移動し、ブレークポイントがヒットすることを期待しています。そうではありません。なぜだめですか?movひょっとして pc に代入するときのセマンティクスが違うのでしょうか (is のようにldr rx, [pc])?

にブレークポイントを設定してもmov pc, r2機能しません。シグナルモードで停止中に GDB にブレークポイントを設定すると問題がありますか? ただし、シグナルの前にブレークポイントを設定しても (Thumb モードで) 動作しません。

mov pc, r2まだ見知らぬ人ですが、まったく実行されていないかのように制御が通過するケースに遭遇しています。しかし、 r12 を修正すると、前の命令が実行されます。

にシングルステップのアナログはありsignal 0ますか?

4

1 に答える 1

3

これは、GDB のバグが原因です。現在、修正を準備中です。https://code.google.com/p/android/issues/detail?id=56962を参照して ください

[編集; 以下の返信で説明されているように、最初は上記の間違った URL にリンクしていました。現在、上記の URL は正しいです。]

私の gerrit 提出物を選択するか、Google が更新された NDK をリリースするのを待つことができます。または、x86 で Linux または Windows を使用している場合は、バイナリを共有できる可能性があります。

Gerrit の提出は: https://android-review.googlesource.com/#/c/61322/

于 2013-05-24T21:04:26.690 に答える