有时使用AndroidStudio调试c++代码时,无法正确的命中代码,观察到AndroidStudio的控制台输出了一些命令:
Launching 'client_tank2018' on Xiaomi Redmi Note 8 Pro. # adb通过am启动app $ adb shell am start -n "com.caohua.tank5/org.cocos2dx.lua.AppActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -D Waiting for application to come online: com.caohua.tank5.test | com.caohua.tank5 Connecting to com.caohua.tank5 Now Launching Native Debug Session $ adb shell # | 用于将一个命令的输出作为另一个命令的输入 cat /data/local/tmp/lldb-server | # run-as以应用程序的上下文身份运行命令,这样就能够访问应用程序的私有文件和目录 # sh -c 是在shell中执行一串字符串命令 # && 是一个逻辑与操作符,用于在前一个命令成功执行后才执行后续的命令 run-as com.caohua.tank5 sh -c 'cat > /data/data/com.caohua.tank5/lldb/bin/lldb-server && # 700 表示用户具备读取、写入和执行权限 chmod 700 /data/data/com.caohua.tank5/lldb/bin/lldb-server' $ adb shell cat /data/local/tmp/start_lldb_server.sh | run-as com.caohua.tank5 sh -c 'cat > /data/data/com.caohua.tank5/lldb/bin/start_lldb_server.sh && chmod 700 /data/data/com.caohua.tank5/lldb/bin/start_lldb_server.sh' # 运行lldb脚本 Starting LLDB server: /data/data/com.caohua.tank5/lldb/bin/start_lldb_server.sh /data/data/com.caohua.tank5/lldb unix-abstract /com.caohua.tank5-0 platform-1689041457869.sock "lldb process:gdb-remote packets" Debugger attached to process 16700 Timed out waiting for java debugger to attach
2个shell命令的作用:将系统目录的lldb-server
和start_lldb_server.sh
拷贝到app内
- start_lldb_server.sh
#!/system/bin/sh # This script launches lldb-server on Android device from application subfolder - /data/data/$packageId/lldb/bin. # Native run configuration is expected to push this script along with lldb-server to the device prior to its execution. # Following command arguments are expected to be passed - lldb package directory and lldb-server listen port. umask 0002 LLDB_DIR=$1 # /data/data/com.caohua.tank5/lldb LISTENER_SCHEME=$2 # unix-abstract DOMAINSOCKET_DIR=$3 # /com.caohua.tank5-0 PLATFORM_SOCKET=$4 # platform-1689041457869.sock LOG_CHANNELS=$5 # "lldb process:gdb-remote packets" BIN_DIR=$LLDB_DIR/bin LOG_DIR=$LLDB_DIR/log TMP_DIR=$LLDB_DIR/tmp PLATFORM_LOG_FILE=$LOG_DIR/platform.log export LLDB_DEBUGSERVER_LOG_FILE=$LOG_DIR/gdb-server.log export LLDB_SERVER_LOG_CHANNELS="$LOG_CHANNELS" export LLDB_DEBUGSERVER_DOMAINSOCKET_DIR=$DOMAINSOCKET_DIR # This directory already exists. Make sure it has the right permissions. # 所有者拥有读、写和执行权限; # 所属组拥有读和执行权限; # 其他用户拥有读和执行权限。 chmod 0775 "$LLDB_DIR" # 清空tmp、log目录 rm -r $TMP_DIR mkdir $TMP_DIR export TMPDIR=$TMP_DIR rm -r $LOG_DIR mkdir $LOG_DIR # LLDB would create these files with more restrictive permissions than our umask above. Make sure # he doesn't get a chance. # "touch" does not exist on pre API-16 devices. This is a poor man's replacement cat </dev/null # 将标准输入重定向为特殊设备文件,/dev/null表示不接收任何输入 >"$LLDB_DEBUGSERVER_LOG_FILE" # 重定向标准输出 log/gdb-server.log 2>"$PLATFORM_LOG_FILE" # 重定向错误输出 log/platform.log cd $TMP_DIR # change cwd $BIN_DIR/lldb-server # 指定 `lldb-server` 运行在平台模式下,用于与调试目标进行通信 platform # 以服务器模式运行 `lldb-server` --server # 指定 `lldb-server` 监听的地址和端口 # `$LISTENER_SCHEME` 是监听方案(如 `unix-abstract` 或 `tcp`) # `$DOMAINSOCKET_DIR` 是 Unix 域套接字目录路径 # `$PLATFORM_SOCKET` 是套接字名称。 # unix-abstract:///com.caohua.tank5-0/platform-1689041457869.sock --listen $LISTENER_SCHEME://$DOMAINSOCKET_DIR/$PLATFORM_SOCKET # log/platform.log --log-file "$PLATFORM_LOG_FILE" # "lldb process:gdb-remote packets" --log-channels "$LOG_CHANNELS" </dev/null # 不接受任何输入 >$LOG_DIR/platform-stdout.log # 标准输出 # 标准输入的文件描述符为 0,标准输出的文件描述符为 1,标准错误输出的文件描述符为 2 2>&1 # 错误输出,&1的意思是合并标准错误和标准输出,并输出到日志文件中
log-channels
每个通道以冒号分隔,每个通道所包含的channel一个空格分隔
default
:默认通道,输出默认的日志信息。gdb-remote
:输出与 gdb 远程调试相关的日志信息。process
:输出与进程和线程相关的日志信息。breakpoint
:输出与断点相关的日志信息。packet
:输出与数据包交换相关的日志信息。communication
:输出与通信相关的日志信息。event
:输出与事件相关的日志信息。platform
:输出与平台相关的日志信息。command
:输出与命令执行相关的日志信息。expression
:输出与表达式求值相关的日志信息。unwind
:输出与栈展开相关的日志信息。- channel1: lldb process
- channel2: gdb-remote packets
lldb-server
LLDB 是一个用于C、C++等语言的调试器,可以帮助开发人员进行调试和分析代码,lldb-server
是调试器的服务器组件,用于与调试目标进行通信和远程调试。
./lldb-server help Usage: ./lldb-server v[ersion] ./lldb-server g[dbserver] [options] # 用于在目标设备上启动 lldb 服务器,并等待本地调试器连接 ./lldb-server p[latform] [options] # 用于从本地调试器连接到已经运行的 lldb 服务器
unix-abstract
unix-abstract
是一种网络连接方案,用于在 Unix 系统上进行本地通信。与传统的 TCP/IP 或 Unix 域套接字不同,unix-abstract
方案使用一个抽象命名空间来创建套接字。
在 --listen $LISTENER_SCHEME://$DOMAINSOCKET_DIR/$PLATFORM_SOCKET
中,$LISTENER_SCHEME
可以被设置为 unix-abstract
,以指定 lldb-server
监听在一个抽象命名空间的 Unix 域套接字上。这样,套接字名称 $PLATFORM_SOCKET
将在该抽象命名空间中创建,而不是在文件系统中创建相应的套接字文件。
使用 unix-abstract
方案可以提供更高的安全性和隔离性,因为套接字名称不会暴露在文件系统中,并且只能通过本地进程间通信来访问。这对于需要在本地进行通信而又希望保持较高安全性的场景非常有用。