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.json
inplatform 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
ここでは、このデモの名前であるアプリ名に従って接続されています。
アプリを起動し、問題なくデバッグします。
とても単純なことではありませんか。