使用 VSCode 远程调试 android NDK 应用程序

Remotely debugging android NDK app using VSCode

我已经尝试了很多方法来让它工作,但到目前为止都无济于事。 我的要求如下:

我知道 gdb 服务器必须 运行 在设备上。 NDK (ndk-gdb) 中的 python 脚本可以将其复制到设备并执行它,然后启动它自己的 shell 可用于设置断点,这在紧要关头很有用,但远不及完整的 GUI 直观。

因此,假设 gdb 服务器现在 运行正在设备上运行,我应该能够连接到它。

我正在尝试在 vs-code 中使用此 'launch.json' 调试配置:

{
    "name": "Debug App on Device",
    "type": "cppdbg",
    "request": "launch",            
    "cwd": "${workspaceRoot}",
    "program":"${workspaceRoot}\android-build\DebugSys\system\bin\app_process64",
            "additionalSOLibSearchPath": "${workspaceRoot}\android-build\obj\local\arm64-v8a",
    "miDebuggerServerAddress": "192.168.1.121:5039",
    "setupCommands": [{
        "text": "set solib-absolute-prefix ${workspaceRoot}/android-build/",
        "ignoreFailures": false
    }],
    "windows": {
         "miDebuggerPath": "C:\Users\luthe\AppData\Local\Android\Sdk\ndk\23.1.7779620\prebuilt\windows-x86_64\bin\gdb.exe",
         "MIMode": "gdb"
         }
},

但是 运行它给了我这个错误:

(目标机器主动拒绝,无法连接)

这可能不是防火墙问题,因为我能够连接到另一台我有 运行ning 的服务器,该服务器由相关应用程序在端口 8080 上启动。

我的 'launch.json' 中是否有错误,或者我是否以完全错误的方式处理所有这些问题。 此外,我的应用程序启动 gdb 服务器是否有意义,还是 better/neutral 让 ndk-gdb 执行它?

好的,所以我仍然无法调试,但我现在至少可以 运行 调试服务器并连接到它。我正在尝试解决的 C++ .so 库的符号文件似乎有问题 here

我在设备上运行使用的过程是这样的:

adb shell forward tcp:5039 localfilesystem:/data/user/0/totga.anthracite/debug_socket
adb shell run-as totga.anthracite rm /data/user/0/totga.anthracite/debug_socket
adb shell run-as totga.anthracite /data/user/0/totga.anthracite/arm64-lldb-server gdbserver unix:///data/user/0/totga.anthracite/debug_socket --attach 1234

其中“1234”是设备上的进程 ID

和 'totga.anthracite' 是我的包名。您需要将 'arm64-lldb-server' 复制到指示的数据目录(我会事先 运行 这一步)并且还记得删除 'debug_socket' 文件 - 之前把事情搞砸了。

在 VSCode 方面,将类似的内容添加到 'launch.json'

{
    "name": "Debug android app on device",
    "type": "cppdbg",
    "request": "launch",            
    "cwd": "${workspaceRoot}",
    "program":"${workspaceRoot}\android-build\DebugSys\system\bin\app_process64",
    "additionalSOLibSearchPath": "${workspaceRoot}\android-build\obj\local\arm64-v8a",
    "miDebuggerServerAddress": "localhost:5039",
    "setupCommands": [
    {
        "text": "set solib-absolute-prefix ${workspaceRoot}/android-build/",
        "ignoreFailures": true
    }
    ],
    "windows": {
        "miDebuggerPath": "${ANDROID_NDK_HOME}/prebuilt/windows-x86_64\bin\gdb.exe",
        "MIMode": "gdb"
    }
}

这应该可以连接,但是,如果像我一样没有符号,您仍然无法调试。希望一旦该问题得到解决,它就会起作用,我将能够在 android 设备上调试本机 C++ 代码。

最后,我避开了 lldb,转而使用 ndk-debug 可以使用的 gdb(目前,他们正在贬低它,尽管它可以工作,而 lldb 显然要么不起作用,要么需要一些设置它不会宣传工作)如果你在 ndk-gdb.py.

中包含 'no_lldb' 标志或将 'use_lldb' 设置为 'False'

然而,如果你想要可视化调试,你不能让 ndk-dbg.py 启动本地 gdb 客户端。我通过创建一个连接到 phone 的最小批处理文件来完成此操作,这可能对将来阅读本文的人有用,以便清楚地了解 android 设备上发生的事情在本地机器上。为清楚起见,此脚本假设只连接了一个设备。

adb shell forward tcp:5039 localfilesystem:/data/user/0/yourorg.yourapp/debug_socket #forward port 5039 to a temporary file called 'debug_socket'. I believe this is called is a 'Unix domain socket'
adb shell run-as yourorg.yourapp rm /data/user/0/yourorg.yourapp/debug_socket #remove the old socket file
adb push libs\arm64-v8a\gdbserver /data/local/tmp/arm64-gdbserver #push the arm64-gdbserver to a temp dir on the device
adb shell run-as yourorg.yourapp "cp /data/local/tmp/arm64-gdbserver /data/user/0/yourorg.yourapp/arm64-gdbserver" #copy the gdbserver to a directory from which it can be run with the privilages of the app you wish to debug
adb shell run-as yourorg.yourapp chmod 700 /data/user/0/yourorg.yourapp/arm64-gdbserver #Ensure 'arm64-gdbserver' is executable
adb shell run-as yourorg.yourapp /data/user/0/yourorg.yourapp/arm64-gdbserver --once +/data/user/0/yourorg.yourapp/debug_socket --attach 1234 #Run gdb server on device, connecting to the societ and the process '1234' (replace with actual PID of your running process)

其中 'yourorg.yourapp' 是您的组织和应用的名称,1234 是要在您的 android 设备上调试的进程的 PID。

在 visual studio 代码中,您需要安装 C++ 扩展和 gdb 调试器扩展。

这是在本地启动 gdb 并连接到 android 设备的 'launch.json' 脚本。请注意,符号在客户端需要,但在 android 设备上不需要,因此可以根据需要删除它们。

{
  "name": "Debug pilkapel on device",
  "type": "cppdbg",
  "request": "launch",            
  "cwd": "${workspaceRoot}",
  "program":"${workspaceRoot}\android-build\DebugSys\system\bin\app_process64",
  "additionalSOLibSearchPath": "${workspaceRoot}\android-build\obj\local\arm64-v8a",
  "miDebuggerServerAddress": "localhost:5039",
  "setupCommands": [
   {
       "text": "set solib-absolute-prefix ${workspaceRoot}/android-build/",
       "ignoreFailures": true
   }
   ],
   "windows": 
    {
      "miDebuggerPath": "C:\Users\luthe\AppData\Local\Android\Sdk\ndk\23.1.7779620\prebuilt\windows-x86_64\bin\gdb.exe",                
      "MIMode": "gdb"
    }
  }

此外,编译器标志对此很重要! 这些是我用于我正在处理的库的调试构建的编译器标志:

LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS) -O0 -g -ggdb -gdwarf64 
LOCAL_CPPFLAGS += -gfull -fstandalone-debug -Wl -gno-split-dwarf 
LOCAL_CPPFLAGS += -fno-unique-internal-linkage-names -fno-direct-access-external-data
LOCAL_CPPFLAGS += -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes 
LOCAL_CPPFLAGS += -Wformat -Werror=format-security -fno-limit-debug-info -fPIC

其中一些对于手头的任务可能是不必要的,我确实使用 lldb 进行了相当多的迭代,但没有任何效果。 对于 gdb,我相信它需要 -gdwarf-5 作为调试格式(我收集的是默认格式)。当我在实验中指定 -gdwarf-4 时,gdb 服务器 运行 但断点不起作用。