简体   繁体   English

如何使用 GDBSERVER 在 Android 上调试应用程序?

[英]How to debug an App on Android with GDBSERVER?

I'm trying to debug a native shared library that my App uses through JNI.我正在尝试调试我的应用程序通过 JNI 使用的本机共享库。 I can attach to a running app just fine with "gdbserver --attach pid" but i need to actually launch my app when i launch the gdbserver command.我可以使用“gdbserver --attach pid”附加到正在运行的应用程序,但我需要在启动 gdbserver 命令时实际启动我的应用程序。

There's a million blog hits on this topic but none of them seem to be clear as to how you launch your app.关于这个主题有 100 万次博客点击,但似乎没有一个人清楚地说明您如何启动您的应用程序。 They all say to just type "gdbserver 10.0.2.2:1234 .\/MyProgram" but what exactly is "MyProgram".他们都说只输入“gdbserver 10.0.2.2:1234 .\/MyProgram”,但究竟什么是“MyProgram”。 Is that MyProgram.apk?那是 MyProgram.apk 吗? Is it MyProgram.so?是 MyProgram.so 吗? Is it some other file that gets created when the app is installed?它是在安装应用程序时创建的其他文件吗? If so, what's its path?如果有,它的路径是什么?

"

While it is possible to develop free standing applications that can be launched directly from the shell as others are describing, it sounds like your code runs within the Android application framework.虽然可以像其他人描述的那样开发可以直接从 shell 启动的独立应用程序,但听起来您的代码在 Android 应用程序框架内运行。 Therefore, you don't have an executable and instead have an APK that contains your Dalvik class files along with other resources including your native shared object.因此,您没有可执行文件,而是有一个 APK,其中包含您的 Dalvik 类文件以及其他资源,包括您的本机共享对象。

Launching an application in an APK involves several steps在 APK 中启动应用程序涉及几个步骤

  1. The system_server process receives an intent requesting your application. system_server 进程接收请求您的应用程序的意图。
  2. The zygote process is told to fork off a new process and run a method of your class. zygote 进程被告知 fork 一个新进程并运行您的类的方法。
  3. Your application runs in the new process.您的应用程序在新进程中运行。

While you can't launch an APK directly by passing an executable to gdbserver, its fairly easy to trigger a launch it from the shell using the am command.虽然您不能通过将可执行文件传递给 gdbserver 来直接启动 APK,但使用am命令从 shell 触发它的启动相当容易。

$ adb -d shell
# am
usage: am [subcommand] [options]

    start an Activity: am start [-D] <INTENT>
        -D: enable debugging

    send a broadcast Intent: am broadcast <INTENT>

    start an Instrumentation: am instrument [flags] <COMPONENT>
        -r: print raw results (otherwise decode REPORT_KEY_STREAMRESULT)
        -e <NAME> <VALUE>: set argument <NAME> to <VALUE>
        -p <FILE>: write profiling data to <FILE>
        -w: wait for instrumentation to finish before returning

    start profiling: am profile <PROCESS> start <FILE>
    stop profiling: am profile <PROCESS> stop

    <INTENT> specifications include these flags:
        [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]
        [-c <CATEGORY> [-c <CATEGORY>] ...]
        [-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...]
        [--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE> ...]
        [-e|--ei <EXTRA_KEY> <EXTRA_INT_VALUE> ...]
        [-n <COMPONENT>] [-f <FLAGS>] [<URI>]


# am start -n com.android.browser/.BrowserActivity
Starting: Intent { cmp=com.android.browser/.BrowserActivity }
#

Once your application is running, use gdbserver --attach <pid> like you have before.应用程序运行后,像以前一样使用gdbserver --attach <pid> If you are lucky your application waits for some user interaction before calling into your native code to give you a chance to attach and set your breakpoints in GDB.如果您幸运的话,您的应用程序会在调用您的本机代码之前等待一些用户交互,以便您有机会在 GDB 中附加和设置断点。

Google provides an official solution to your problem: 'ndk-gdb' Google 为您的问题提供了官方解决方案:'ndk-gdb'

It is included in the NDK.它包含在 NDK 中。 IIRC, it requires that you have a copy of gdbserver bundled up inside your APK; IIRC,它要求您在 APK 中捆绑了 gdbserver 的副本; IIRC, this will happen automatically if you built your APK with 'ndk-build', and specified the appropriate arguments. IIRC,如果您使用“ndk-build”构建 APK 并指定适当的参数,这将自动发生。

Please see Google's documentation in $NDK/docs/NDK-BUILD.html and $NDK/docs/NDK-GDB.html请参阅 $NDK/docs/NDK-BUILD.html 和 $NDK/docs/NDK-GDB.html 中的 Google 文档

</ryan> </ryan>

For the gdbserver executable, I just copied it from the NDK folder of the Android SDK:对于 gdbserver 可执行文件,我只是从 Android SDK 的 NDK 文件夹中复制了它:

  1. Download Android NDK from SDK tools tab of Android Studio preferences.从 Android Studio 首选项的 SDK 工具选项卡下载 Android NDK。
  2. Copy gdbserver to the rooted device: adb push {android-sdk}/ndk/{version}/prebuilt/android-arm64/gdbserver/gdbserver /data/local/tmp将 gdbserver 复制到 root 设备: adb push {android-sdk}/ndk/{version}/prebuilt/android-arm64/gdbserver/gdbserver /data/local/tmp

To run gdbserver, with the device plugged in:要在插入设备的情况下运行 gdbserver:

  1. adb shell su -c setenforce 0
  2. In the device, accept superuser access rights of shell在设备中,接受shell的超级用户访问权限
  3. Launch the app you want to debug启动您要调试的应用程序
  4. adb shell ps | grep {package-name}
  5. Copy the process id (2nd column)复制进程 ID(第二列)
  6. adb shell
  7. cd /data/local/tmp
  8. su -c ./gdbserver :<any-port-number> --attach <pid> (app will freeze) su -c ./gdbserver :<any-port-number> --attach <pid> (应用程序将冻结)

For the gdbclient executable, I had to build it from the gdb source code to configure the correct architecture (arm64) for the Android device.对于 gdbclient 可执行文件,我必须从gdb 源代码构建它,以便为 Android 设备配置正确的架构 (arm64)。 On a separate mac terminal window/tab:在单独的 mac 终端窗口/选项卡上:

  1. cd gdb-10.1
  2. ./configure --target=aarch64-linux-android && make -j8 && sudo make install
  3. aarch64-linux-android-gdb
  4. set sysroot
  5. target remote <phone-ip-address>:<port-number-above>
  6. continue (to unfreeze app) continue (解冻应用程序)
  7. Start debugging.开始调试。
/gdb-9.1/arm64/gdb/../../gdb/python/py-cmd.c:191: undefined reference to `PyUnicodeUCS2_Decode'

@Siklab.ph sorry, In compile i got a python error ,Then I recompile python with option ./configure --enable-unicode=ucs2 @Siklab.ph 抱歉,在编译时出现 python 错误,然后我使用选项 ./configure --enable-unicode=ucs2 重新编译 python

But got a same error .但得到了同样的错误。

do you have any way to fix it?你有什么办法解决吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM