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/

Source: https://habr.com/ru/post/J144672/


All Articles