【问题标题】:Debugging Android NDK C/C++ code in Eclipse - breakpoints are not hit在 Eclipse 中调试 Android NDK C/C++ 代码 - 未命中断点
【发布时间】:2013-07-16 07:41:04
【问题描述】:

我下载了适用于 Linux 和 Android NDK 的 Android SDK Bundle。安装了ADT,我安装了CDT。

我创建了一个 Android 项目并添加了原生支持 (jni)。然后我用 java 代码编写了本机函数,该函数以 c++ 代码导出。我在 C++ 代码中定义了这个函数。

Java 代码:

static {
    System.loadLibrary("test");
}

private native String get_text_from_cpp();

c++代码(h):

extern "C"{
   JNIEXPORT jstring JNICALL Java_com_example_test_MainActivity_get_1text_1from_1cpp(JNIEnv *, jobject);
}

c++代码(cpp):

JNIEXPORT jstring JNICALL Java_com_example_test_MainActivity_get_1text_1from_1cpp(JNIEnv * env, jobject){
    return env->NewStringUTF( "hello from C++" );
}

代码可以正常工作。但是当我在 c++ 代码中设置断点时,它没有被命中。

build-nkd NDK_DEBUG = 1 - 包含

我遵循了这个指示http://tools.android.com/recent/usingthendkplugin

jni/ 中的 Android.mk 具有 LOCAL_CFLAGS := -g

我已经阅读了很多信息,但我无法自定义 Eclipse。请帮助任何人。

PS:对不起,我的英语不是我的母语。我写作有困难。

添加:在控制台调试期间也显示: “警告:无法加载 95 个库的共享库符号,例如 /system/bin/linker。 使用“info sharedlibrary”命令查看完整列表。 你需要“set solib-search-path”还是“set sysroot”? 警告:无法找到动态链接器断点函数。 GDB 最终会重试。同时,很可能 GDB 无法调试共享库初始化程序 或在 dlopen() 之后解决挂起的断点。”

【问题讨论】:

  • 也许,您运行了 Debug,它启动了 Java 调试器?您应该右键单击项目并选择“调试为”->“android 本机应用程序”
  • 是的,我选择了“debug as”->“android native application”。在“Debug Configurates”中添加了新配置(在“Android Native Application”中)gyazo.com/567ae4fa0e8aa2363676789b7df780be
  • 可能,你的app很早就执行了JNI函数,导致调试器还没准备好?从您发布的代码中,不清楚调用本机方法的位置。我建议在您的活动中使用一些按钮来启动本机方法。然后,您有机会尝试几次。
  • 顺便说一句,关于 95 个库的警告是完全正常的。这些是您不想调试的系统库,并且没有源代码。
  • 在onCreate()方法中调用native方法。哪些是按钮?

标签: android eclipse debugging android-ndk java-native-interface


【解决方案1】:

我使用的技巧是将 usleep 调用作为调试代码中的第一行。

这会让你的线程休眠,让调试器有机会为你做好准备。

#include <unistd.h>

.
.
.

#ifndef NDEBUG
usleep(5000 * 1000);
#endif

【讨论】:

    【解决方案2】:

    在 大量 在 Eclipse 上进行调试之后,这是我的秘诀:

    执行通常的步骤:

    • 在加载本机库之前添加android.os.Debug.waitForDebugger();。这可能会有所帮助。
    • 在Application.mk 中添加APP_OPTIM := debug
    • 使用ndk-build NDK_DEBUG=1 构建

    然后,我发现了不同的地方:

    • 打开控制台并运行:

    adb pull /system/bin/linker &lt;your_project_base_dir&gt;/obj/local/armeabi/linker

    根据您的设备,您可能需要编写armeabi 或armeabi-v7a。您只需要执行一次(我注意到手动运行ndk-gdb 正在执行此操作。手动执行该命令,断点开始工作)

    • 最后,使用菜单“Run -> Debug As -> Android Native Application”进行调试

    【讨论】:

    • 也拉取其他一些库(至少在 4.9 工具链中)
    • 什么是 /system/bin/linker ?我在哪里可以找到这个链接。我是 Windows 用户。
    【解决方案3】:

    您可以使用 ARM 提供的 DS-5 CE Android 调试工具作为 Eclipse 的插件。它工作得非常好,并为调试提供了一个非常好的和简单的 UI。从我个人的经验来看,它比调试 ndk 应用程序的传统方式要好得多。

    请参考以下链接,详细了解如何使用 DS-5 调试器:

    https://developer.arm.com/products/software-development-tools/ds-5-development-studio/resources/tutorials/android-native-app-debug-tutorial

    【讨论】:

    • 感谢您的链接。我尝试使用 DS-5,但是当我创建新的调试配置时,我无法从“连接”下拉框中选择要连接的设备,那里什么都没有。
    【解决方案4】:

    您的应用很早就执行了 JNI 函数,因此调试器还没有准备好。不幸的是,gdb 建立远程连接需要一段时间,请参阅 http://visualgdb.com/documentation/appstartup

    与其与风车搏斗,不如向您的活动添加一个按钮,并调用该按钮的相同本机方法 onClick() - 捕获断点会更容易。

    顺便说一句,关于 95 个库的警告是完全正常的。这些是您不想调试的系统库,并且没有源代码。

    【讨论】:

      【解决方案5】:

      考虑添加:

      android.os.Debug.waitForDebugger();

      在您的本机调用之前,这会使您的应用等待调试器附加,可以帮助您避免休眠/使用按钮。

      【讨论】:

        【解决方案6】:

        我遇到了这个问题,唯一对我有用的是放

        Thread.sleep(2000);
        

        在加载 JNI 库之前。这给了调试器足够的时间在调用System.loadLibrary 导致应用程序崩溃之前附加。帮助我找到了问题 C++ 代码。

        【讨论】:

          猜你喜欢
          • 2021-09-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-12-21
          • 2014-05-31
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多