【问题标题】:How to debug an App on Android with GDBSERVER?如何使用 GDBSERVER 在 Android 上调试应用程序?
【发布时间】:2010-01-13 12:57:45
【问题描述】:

我正在尝试调试我的应用程序通过 JNI 使用的本机共享库。我可以使用“gdbserver --attach pid”附加到正在运行的应用程序,但我需要在启动 gdbserver 命令时实际启动我的应用程序。

关于此主题的博客点击量达到一百万,但似乎没有一个人清楚地说明您如何启动您的应用程序。他们都说只输入“gdbserver 10.0.2.2:1234 ./MyProgram”,但究竟什么是“MyProgram”。那是 MyProgram.apk 吗?是 MyProgram.so 吗?它是在安装应用程序时创建的其他文件吗?如果有,它的路径是什么?

【问题讨论】:

    标签: android debugging gdb java-native-interface gdbserver


    【解决方案1】:

    对于 gdbserver 可执行文件,我只是从 Android SDK 的 NDK 文件夹中复制了它:

    1. 从 Android Studio 首选项的 SDK 工具选项卡下载 Android NDK。
    2. 将 gdbserver 复制到有根设备: adb push {android-sdk}/ndk/{version}/prebuilt/android-arm64/gdbserver/gdbserver /data/local/tmp

    在插入设备的情况下运行 gdbserver:

    1. adb shell su -c setenforce 0
    2. 在设备中,接受shell的超级用户访问权限
    3. 启动您要调试的应用程序
    4. adb shell ps | grep {package-name}
    5. 复制进程 ID(第 2 列)
    6. adb shell
    7. cd /data/local/tmp
    8. su -c ./gdbserver :<any-port-number> --attach <pid>(应用将冻结)

    对于 gdbclient 可执行文件,我必须从 gdb source code 构建它,以便为 Android 设备配置正确的架构 (arm64)。在单独的 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(解冻应用)
    7. 开始调试。

    【讨论】:

      【解决方案2】:

      虽然可以像其他人所描述的那样开发可以直接从 shell 启动的独立应用程序,但听起来您的代码在 Android 应用程序框架中运行。因此,您没有可执行文件,而是有一个 APK,其中包含您的 Dalvik 类文件以及其他资源,包括您的本机共享对象。

      在 APK 中启动应用程序涉及几个步骤

      1. system_server 进程接收到请求您的应用程序的意图。
      2. zygote 进程被告知派生一个新进程并运行您的类的方法。
      3. 您的应用程序在新进程中运行。

      虽然您不能通过将可执行文件传递给 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 }
      #
      

      一旦您的应用程序运行,请像以前一样使用gdbserver --attach &lt;pid&gt;。如果幸运的话,您的应用程序会在调用您的本机代码之前等待一些用户交互,让您有机会在 GDB 中附加和设置断点。

      【讨论】:

        【解决方案3】:

        Google 为您的问题提供了官方解决方案:'ndk-gdb'

        它包含在 NDK 中。 IIRC,它要求您在 APK 中捆绑 gdbserver 的副本; IIRC,如果您使用“ndk-build”构建 APK 并指定适当的参数,这将自动发生。

        请参阅 $NDK/docs/NDK-BUILD.html 和 $NDK/docs/NDK-GDB.html 中的 Google 文档

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-03-10
          • 2014-02-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多