WindowsでのネイティブAndroid NDKコードのデバッグ

はじめに



良い一日!



かつて、アプリケーションの理解不能な転倒をキャッチするタスクに直面しました。 私が知る限り、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();

}








上で書いたように、アプリケーションを起動した後、指をクリックするだけで、アプリケーションがクラッシュします。 私たちの仕事は、落ちてバックトレースを見る場所を見つけることです。 それでは始めましょう。



ツール



私たちは自由に持っていなければなりません:





準備する



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.so

android-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/



All Articles