Android および iOS で LLDB を使用して Rust プログラムをデバッグする

ここに画像の説明を挿入

Rust で出力されたログ情報はprintln!()Xcode では表示できますが、Android Studio では表示できません。したがって、Android はandroid_logger を使用してログ出力を実現できます。ただし、開発時のみログを出力してデバッグするだけでは十分ではなく、デバッグ モードも必要です。ということでこの記事の内容となります。

LLDB(低レベル デバッガー) は、新世代の軽量で高性能なデバッガーであり、XcodeデフォルトAndroid Studioのデバッガーです。Android 開発の学生に比べて、iOS の学生は Android 開発に精通しています。Rust は LLDB ベースのデバッグ ツールチェーンを提供するため、それを使用して Rust プログラムをデバッグできます。

準備

まず、「Rust ライブラリのクロスコンパイルと Android および iOS での使用」を読んで、Rust プログラムを Android または iOS に統合する方法を学ぶことをお勧めします。この記事の例では、この記事のデモも使用しています。

Android であっても iOS であっても、この記事のコンテンツではCodeLLDBデバッグにプラグインを使用するため、VS Code とこのプラグインがインストールされている必要があります。

ここに画像の説明を挿入

アンドロイド

具体操作

Android プロジェクトでは、デバッグ so ファイルが圧縮および最適化されないように構成する必要があることに注意してください。また、デバッグによって生成される so ファイルに注意してください。

android {
    
    
	...

	packagingOptions{
    
    
    	doNotStrip "**/libxxx.so"
	}
}

1.lldb-server を電話機にプッシュします

adb push lldb-server /data/local/tmp/

デバイスが以前に JNI コードをデバッグしたことがある場合、このファイルは/data/local/tmp/ディレクトリに存在するため、この手順は無視できます。同様に、このファイルがない場合は、新しいネイティブ C++ プロジェクトを作成して調整できます。または、ndk に移動してファイルを
画像の説明を追加してください
見つけます。lldb-server

find . -name lldb-server

画像の説明を追加してください
たとえば、私の携帯電話は 64 ビットなので、aarch64次のものを選択します。次に、lldb-server電話機にプッシュします。

2.アプリを起動してpidを取得します。

# 启动App
adb shell am start -a android.intent.action.MAIN -n <package-name>/.<activity-name>
# 获取pid
adb shell pidof <package-name>

3. lldbサーバーを起動します

adb shell /data/local/tmp/lldb-server p --server --listen "*:9876"

4. Rustプロジェクトのデバッグ構成

launch.json構成は以下の通りで、対象プロセスにアタッチする機能です。

{
    
    
    "version": "0.2.0",
    "configurations": [
        {
    
    
            "type": "lldb",
            "request": "attach",
            "name": "Android",
            "pid": "xxx",
            "initCommands": [
                "platform select remote-android",
                "platform connect connect://localhost:9876",
                "file target/aarch64-linux-android/debug/libxxx.so",
            ]
        }
    ]
}
  • pid前の手順で取得したとおりに入力します。
  • target/aarch64-linux-android/debug/librust_demo.soデバッグ バイナリの場所については、Android プロジェクトと同じファイルを保持します。

他の部分は変更できません。これにより、デバッグの実行時にデバッグ ポイントを中断してデバッグできます。
画像の説明を追加してください

質問

上記は実際には root 化されたデバイスにのみ適しています。それ以外の場合は、attach xxx実行時に許可を求められません。そのため、最初はエミュレータを使用し、次にデバッグするための root 権限を取得しました。

その後、Android の基本的な開発実践: Native Crash の gdb デバッグ部分を分析する方法を見て、解決策を見つけました。

Android Studio の lldb デバッガーをネイティブ デバッグに使用すると、次の出力が得られます。

画像の説明を追加してください

上記からわかるように、Android Studio は cat 出力lldb-serverと run-as を使用して、アプリケーションのアクセス許可を取得して cat を実行し、lldb-serverアプリのプライベート データ ディレクトリに書き込み、chmod 700実行可能アクセス許可を増やします。次に、同じ方法を使用してstart_lldb_server.shシェル スクリプトをアプリ データ ディレクトリに送信します。最後に、アプリのアクセス許可を使用してスクリプトを実行して、lldb を開始します。

実際、root 権限がなくてもデバッグできるのに、なぜデバッグできないのか、この疑問を注意深く考えてください。したがって、次のような宿題をコピーすることになります。

adb shell "cat /data/local/tmp/lldb-server 
| run-as <package-name> sh -c 'cat > /data/data/<package-name>/lldb/bin/lldb-server 
&& chmod 700 /data/data/<package-name>/lldb/bin/lldb-server'"

# 启动lldb-server
adb shell run-as <package-name> ./lldb/bin/lldb-server p --server --listen "*:9876"

開始するとOperation not permittedエラーが報告されます。このメソッドに実装されているunix-abstractメソッドを使用できます。start_lldb_server.sh

adb shell run-as <package-name> ./lldb/bin/lldb-server p --server --listen unix-abstract:///<package-name>/debug.sock

対応するlaunch.jsoninplatform connect connect://localhost:9876は に置き換えられます
platform connect unix-abstract-connect:///<package-name>/debug.sock

もちろん、<package-name>/debug.sock名前は任意に定義できますが、ここでは競合を避けるために推奨される形式を示します。

最適化

4番目のステップでは、pidを毎回手動で置き換える必要があり、これが非常に面倒です。これを最適化して pid を動的に取得できます。

tasks.json次の内容のファイルを作成します。

{
    
    
    "version": "2.0.0",
    "tasks": [
        {
    
    
            "label": "get pid",
            "type": "shell",
            "command": "adb shell pidof <package-name> | tr -d '\n' > ${workspaceRoot}/pid.txt"
        }
    ]
}

この機能は、pid を取得し、それを pid.txt ファイルに書き込むことです。

launch.json次のように変更します。

{
    
    
    "version": "0.2.0",
    "configurations": [
        {
    
    
            "type": "lldb",
            "request": "attach",
            "name": "Attach",
            "pid": "${input:pid}",
            "preLaunchTask": "get pid",
            "initCommands": [
                "platform select remote-android",
                "platform connect connect://localhost:9876",
                "file target/aarch64-linux-android/debug/libxxx.so",
            ]
        }
    ],
    "inputs": [
        {
    
    
            "id": "pid",
            "type": "command",
            "command": "extension.commandvariable.file.content",
            "args": {
    
    
                "fileName": "${workspaceFolder}/pid.txt"
            }
        }
    ]
}

実行時に、pid.txtファイルの内容を pid として読み取ります。

  • ここでの使用法では、プラグインをextension.commandvariable.file.contentインストールするために vs code が必要であることに注意してください。Command Variable
  • この方法の問題は、ファイル内の pid が最初に読み取られ、それがget pid先に実行されることです。したがって、正しい pid を取得するには、もう一度実行する必要があります。ただし、アプリを強制終了しない限りpidは変化しないので、大きな問題にはなりません。

Android は上記の方法で Rust コードをデバッグできますが、結局のところ、as から直接サポートされる利便性はありません。今のところ、何もしないよりは話し合ったほうが良いでしょう。

iOS

iOS は全体として Android に比べてはるかにシンプルで便利ですが、まず Android と同様に静的ライブラリのデバッグ パッケージ (コマンド) を使用する必要がありますcargo lipo次にFrameworks,Libraries,and Embedded Content、 でLibrary Search Paths設定しますlibxxx.a
画像の説明を追加してください
私はエミュレータを使用するので、x86_64-apple-iosここでフォルダを選択します。

launch.json構成は次のとおりです。

{
    
    
    "version": "0.2.0",
    "configurations": [
        {
    
    
            "type": "lldb",
            "request": "attach",
            "name": "iOS",
            "program": "RustDemo",
        },
    ]
}

RustDemoここでは、このデモの名前であるアプリ名に従って接続されています。

アプリを起動し、問題なくデバッグします。
画像の説明を追加してください
とても単純なことではありませんか。

参考

おすすめ

転載: blog.csdn.net/qq_17766199/article/details/129402080