はじめに
良い一日!
かつて、アプリケーションの理解不能な転倒をキャッチするタスクに直面しました。 私が知る限り、Android NDKはC ++コードをデバッグする機能を提供していましたが、その方法を漠然と想像していました。 残念ながら、ネイティブコードのデバッグに関する実用的な情報はほとんどありませんでした。 この問題に数晩費やしましたが、私はまだデバッグを見つけてセットアップしました。 次に、これをどのように行うことができるかについて説明します。また、私の道を繰り返すことにした場合、どのようなレーキが期待できるかについても説明します。
便宜上、デバッグアプリケーションプロジェクト-NdkDebugTestを作成しました。 アプリケーションに黒い画面が表示され、画面をクリックすると、ネイティブコードが呼び出され、アプリケーションが強制終了されます。 このプロジェクトは、2つのjavaファイルと1つのjniファイルで構成されています。 これは、それぞれアクティビティコード、JNIシェルのコード、およびネイティブコードです。
アクティビティコードは非常にシンプルです-タッチするだけで、ネイティブのOnInput関数が呼び出されます。 また、アクティビティを作成すると、空のDoInit()メソッドが呼び出されます。このタスクのタスクは、JniWrapper.javaからネイティブライブラリの静的ロードを開始することです(これが行われない場合は、以下を参照してください)。
コードは次のとおりです。
package fishrungames.ndkdebugtest;
//...
public class MainActivity extends Activity
{
protected void onCreate(Bundle icicle)
{
super.onCreate(icicle);
JniWrapper.DoInit();
}
public boolean onTouchEvent(MotionEvent event)
{
float x = event.getX();
float y = event.getY();
JniWrapper.OnInput(x, y);
return true;
}
}
Jniシェルも非常に簡単です。
package fishrungames.ndkdebugtest;
public class JniWrapper
{
static {
System.loadLibrary("gnustl_shared");
System.loadLibrary("NdkDebugTestLib");
}
public static void DoInit()
{
//To force libraries to load
}
public static native void OnInput(float x, float y);
}
まあ、実際にはネイティブコード。 ここでは、アプリケーションを強制終了する別の関数がJni関数から呼び出されます。
#include "android_api.h"
void crusher()
{
int *x = 0;
*x = 1;
}
JNIEXPORT void JNICALL Java_fishrungames_ndkdebugtest_JniWrapper_OnInput(JNIEnv * env, jobject obj, float x, float y)
{
crusher();
}
上で書いたように、アプリケーションを起動した後、指をクリックするだけで、アプリケーションがクラッシュします。 私たちの仕事は、落ちてバックトレースを見る場所を見つけることです。 それでは始めましょう。
ツール
私たちは自由に持っていなければなりません:
- オープンなNdkBuildTestプロジェクトを使用したEclipse
- シグウィン
- インストールされたandroid-sdk
- インストールされたandroid-ndk、PATH環境変数で指定する必要があるパス。 ndkバージョンが古いほど良い(android-ndk-r8を使用した)
準備する
1)マニフェストでdebuggable =“ true”パラメーターが設定されていることを確認します。
<application android:icon = "@ drawable / ic_menu_template" android:label = "NdkDebugTest" android:debuggable = "true">2)Application.mkで、次の行を追加します。
APP_OPTIM:=デバッグこのパラメーターは、私が間違えなければ、ライブラリーをコピーするときにストリッピング(未使用文字の削除)を除去し、デバッグに役立つ他のいくつかのことを行います。
Android.mkでは、-g -ggdb -O0パラメーターをLOCAL_CFLAGSに追加し、-sおよび-S(存在する場合)をLOCAL_LDLIBSパラメーターから削除する必要があります。
3)その後、Cygwinを実行し、プロジェクトのあるディレクトリに移動して、キーNDK_DEBUG = 1でアセンブリを開始します。
ndk-build NDK_DEBUG = 1すべてが正しく行われると、gdb.setupおよびgdbserverファイルがサブディレクトリlibs / <platform> /のプロジェクトディレクトリに表示されます。
4)gdb.setupには、基本的なデバッガー設定が示されています-ヘッダーとライブラリーを探すディレクトリ。 ヘッダーへのすべてのパスが示されているかどうかを確認し、必要に応じて独自のパスを追加する必要があります。
熊手があります。 何らかの理由で、このファイルの各再構築で改行文字が失われます。そのため、設定が読み取られません。 ファイルがUNIXの改行を使用していることを確認してください。 ndk-buildを呼び出すたびに、別の改行でgdb.setupを再保存する必要がありました!デバッガーが起動すると、このファイル(gdb.setup)に他のパラメーターが自動的に追加され、obj / local / <platform> /にコピーされます。 アプリケーションが動作するために必要なすべてのネイティブライブラリもobj / local / <platform> /に保存されます。 アセンブリが正常に実行された場合、ライブラリにはdebazhnye文字が含まれています。 疑問がある場合は、nmユーティリティを使用してCygwinコンソールから直接太字の有無を確認し、目的のsoファイルをパラメーターとして指定できます。
nm /obj/local/armeabi/libNdkDebugLib.soandroid-ndkの一部の古いバージョンでは、build / core / build-binary.mkファイルを編集することも推奨されました。つまり、次の行を変更します。
$(非表示)$(cmd-stripを呼び出す、$(PRIVATE_DST))ライン上:
ifneq($(APP_OPTIM)、デバッグ)
$(非表示)$(cmd-stripを呼び出す、$(PRIVATE_DST))
エンディフデバッグ
すべてのデバッグの準備ができました。 eclipseでデバッグを開始し、デバッガーがピックアップするまで待ちます。 次に、cygwinでプロジェクトのあるディレクトリに移動し、ndk-gdbネイティブデバッガーを実行します。 --adbパラメーターは、android-sdkの一部であるadbへのパスを指定します。
ここに別の熊手があります。 起動前にすべてのネイティブライブラリ(この場合はNdkDebugTestLib)がロードされていることを確認してください! これを確認するには、ライブラリのロード時にブレークポイントを設定します。すべてが正しく実行されると、シンボルがロードされていないライブラリの長いリストが表示されます。 ライブラリがそれらの中にないことを確認してください(この場合、libNdkDebugTestLib.so)。
すべてが順調に進むと、次の入力を求めるプロンプトが表示されます。

continueコマンドを続行します。 次に、デバイス画面上で指を押すと、アプリケーションがクラッシュし、ドロップポイントが示されます。

* x = 1を呼び出すときにクラッシュが発生しました。 予想どおり、jni / android_api.cppの6行目。
バックトレースを導入します-そして、クラッシュにつながった関数呼び出しのスタックを確認します:

おわりに
さて、目標は達成されました-アプリケーションクラッシュサイトを見つけ、コールスタックを確認しました。 デバッガーを使用すると、ブレークポイントの設定、式の評価などを行うことができますが、コマンドラインデバッガーの使用方法に関する情報を見つけるのに問題はありません。
ここにプロジェクトへのリンクがあります。これは記事
http://fishrungames.ru/4habr/NdkDebugTest.rarで説明されています。
ソース
http://vilimpoc.org/blog/2010/09/23/hello-gdbserver-a-debuggable-jni-example-for-android/http://blog.sephiroth.it/2010/12/14/how-to-debug-native-code-with-android/http://mhandroid.wordpress.com/2011/01/23/using-eclipse-for-android-cc-debugging/