Android でネイティブ ライブラリの読み込みイベントにブレークポイントを設定するにはどうすればよいですか?
dlopen()にブレークポイントを設定することは良い出発点になると思いますが、 libc.soと/system/bin/linkerのシンボルがロードされている場合でも、gdb は dlopen 関数を見つけることができません。
nmツールもdlopen()の場所を報告しないため、Androidは.soファイルの特別な形式を使用しているようです。
ブレークポイントを手動で設定できるように、名前で関数アドレスを見つけるのに役立つ問題または Android 固有の .so ダンプ ツールの回避策はありますか?
編集:
私がやろうとしているのは、任意のネイティブ ライブラリがロードされたとき、つまりコード (ライブラリ内でさえない) がdlopen()関数を呼び出したときにトリガーされるブレークポイントを設定することです。
問題は、Android GDB が保留中のブレークポイントをサポートしていないことです。私のシナリオは次のようなものです:
- アプリを起動して停止します。
- アプリが再開され、ネイティブ ライブラリが読み込まれます。
- 私の関数はライブラリから呼び出されます (アプリがロードされたときに 1 回だけ)。
#1の後にブレークポイントを設定すると、ライブラリがまだ存在せず、android-gdbが再バインドできないため機能しません。プログラムを実行させてから、もう一度停止してブレークポイントを設定すると、すでに #3 を過ぎているため、ブレークポイントは役に立たなくなります。
#1 でブレークポイントをdlopen()に設定して回避しようとしています。次に、ライブラリにヒットしてロードすると (つまり #2)、実際のブレークポイントを設定します。
通常の ARM nm と objdump を使用しても効果はありません。libc.so を NM'ing すると、dlopen()が未定義であることがわかります。
00016188 T dlmemalign
U dlopen
00016338 T dlpvalloc
/ system/bin/linkerバイナリには物理的にdlopenテキスト ( .rodataセクションの最初のバイト) が含まれていますが、nmには次のテキストが表示されます。
arm-linux-androideabi-nm.exe: linker: No symbols
objdump で逆アセンブルすると、シンボル名が得られません。
Android ソースを探し回ると、次のソース ファイルが明らかになりました。
http://dexandroid.googlecode.com/svn/trunk/bionic/linker/dlfcn.c
dlopen() は /system/bin/linker 内で実際に定義されているように見えますが、非標準のシンボル解決メカニズムを使用しています (少なくとも、最初のコメントに基づいて):
/* This file hijacks the symbols stubbed out in libdl.so. */
質問に戻ると、ライブラリがロードされたときに実際のブレークポイントを設定するために、どうすればdlopen()にブレークポイントを設定できますか?