在Android与iOS中使用LLDB调试Rust程序
Posted 唯鹿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Android与iOS中使用LLDB调试Rust程序相关的知识,希望对你有一定的参考价值。
在Rust中通过println!()
打印的日志信息在Xcode中可以显示,但是android Studio里不显示。所以Android可以使用android_logger实现日志输出。但是开发中仅使用打印日志的方式进行调试还是不够的,我们还需要debug调式。所以有了本篇的内容。
LLDB
(Low Level Debugger)是新一代轻量级高性能调试器, 是Xcode
和Android Studio
中的默认调试器。相较于Android开发同学,ios同学更熟悉它。Rust提供了基于LLDB的调试工具链,所以我们就可以借此用来调试Rust程序。
准备工作
首先建议你先阅读Rust库交叉编译以及在Android与iOS中使用这篇内容,了解如何将Rust程序集成进Android或iOS。本篇的例子也是使用此篇的demo。
不论是Android还是iOS,我们本篇的内容都使用CodeLLDB
插件进行调试,所以你必须有安装 VS Code和此插件。
Android
具体操作
注意Android项目中我们需要将调试的so文件配置为不压缩优化,同时注意使用debug生成的so文件。
android
...
packagingOptions
doNotStrip "**/libxxx.so"
1.push lldb-server到手机
adb push lldb-server /data/local/tmp/
如果之前你的设备有调式过JNI代码,那么此文件就会存在/data/local/tmp/
目录下,可以忽略这一步。同理,如果你没有这个文件,可以新建一个Native C++项目调式一下。
或者去ndk中寻找lldb-server
文件:
find . -name lldb-server
比如我的手机64位的, 所以选择aarch64
下的。然后pushlldb-server
到手机。
2.启动App,然后获取pid
# 启动App
adb shell am start -a android.intent.action.MAIN -n <package-name>/.<activity-name>
# 获取pid
adb shell pidof <package-name>
3.启动lldb-server
adb shell /data/local/tmp/lldb-server p --server --listen "*:9876"
4.rust项目debug配置
launch.json
配置如下,作用是attch到目标进程。
"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项目中的文件一致。
其他部分可以不用修改。然后Debug运行就可以打断点进行调式了。
问题
以上其实只适合root设备,否则执行attach xxx
时会提示无权限。所以一开始我是使用的模拟器,然后获取root权限进行调试的。
后面看到了Android基础开发实践:如何分析Native Crash这篇gdb调试部分,找到了解决思路。
我们用Android Studio的lldb调试器进行native调试时有如下的输出:
从上面可以看出,Android Studio通过cat输出
lldb-server
并run-as以应用的权限执行cat进行接收,然后将lldb-server
写入到app的私有数据目录,紧接着chmod 700
增加可执行权限。然后使用同样的方式将一个shell脚本start_lldb_server.sh
发送到app数据目录。最后以app的权限运行脚本启动lldb。
其实这个问题仔细想想,为啥as可以不用root就能调试,我们不行。所以就是抄as的作业:
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
中的platform connect connect://localhost:9876
替换为
platform connect unix-abstract-connect:///<package-name>/debug.sock
。
当然<package-name>/debug.sock
名字随你怎么定义,这里只是给了一个建议格式,避免冲突。
优化
在第四步中,我们需要每次手动替换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只要app不杀死就不会变动,所以问题不大。
Android虽然可以通过上述方法实现调试Rust代码,但毕竟没有as直接支持来的方便。目前来说,聊胜于无。
iOS
iOS整体比Android简单方便很多,首先和Android一样需要用debug静态库包(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",
,
]
这里是根据App名称连接的,RustDemo
就是这个的demo的名称。
启动App,然后debug就好了。
是不是非常简单。
参考
以上是关于在Android与iOS中使用LLDB调试Rust程序的主要内容,如果未能解决你的问题,请参考以下文章