【问题标题】:Step In with native code leads to garbage in Android Studio使用本机代码单步执行会导致 Android Studio 出现垃圾
【发布时间】:2016-10-13 19:00:07
【问题描述】:

我有在 Android Studio 中使用 Gradle 构建的本机代码。大多数调试似乎在 C++ 中运行良好,但我只是添加了一个新类,当我尝试进入函数调用时,它会将我带到一个完全不相关的代码区域中的一个绝对奇怪的位置。

例如,我有以下带断点的代码行:

SemVer ver_cl = PlatformHelper::getAppVersion();

我运行“Step In”,最终在看似任意的代码行上实现了gnu-libstdc++ hashtable.h。

我正在模拟器中运行。我已确保将我的项目同步到 Gradle 文件,但我不确定是什么导致了这种行为。

【问题讨论】:

    标签: android c++ android-studio gradle android-ndk


    【解决方案1】:

    PlatformHelper::getAppVersion(); 的实现可以洞察问题。在这种特殊情况下,该方法没有返回值。对于historical reasons,它在 C++ 中不是错误,但现代编译器通常会在这种情况下触发警告,通过为 GCC 添加-Werror 编译标志,您可以强制它将警告视为错误。当非 void 方法没有返回值时,堆栈被破坏并且控制返回到一个随机位置。 aardvarkk 很“幸运”,因为地址恰好是有效的。

    可以看到类似行为的另一种情况是,当您使用优化(除 -O0 之外的任何内容)编译代码时。最强大的优化技术之一是内联:函数体直接插入到调用它们的位置。这对模板特别有用。此过程的缺点是某些功能被完全消除,并且它们在堆栈跟踪中不可见。因此,当您进入 PlatformHelper::getAppVersion(); 时,您可能会直接进入使用 hashmap 的内部某个地方,因为在调用 getAppVersion 和使用 hashmap 之间的所有代码都已被优化掉。但是这种情况下你的程序会正常运行,只是调试会有点麻烦。

    【讨论】:

    • 我不相信这是怎么回事。函数体现在实际上什么都没有——只有一行说:int n = 0;,所以我可以看看它是否落在其中。话虽如此,我现在意识到我现在实际上并没有返回 SemVer 结构,并且由于某种原因编译器没有抱怨这个?!看起来很奇怪……
    • 编译器确实不会抱怨没有从函数返回值。在这种情况下,当您从函数返回时,您的堆栈已损坏,事情可能会变得非常奇怪。
    • 天哪——这完全是因为我没有从函数返回有效值。我已经习惯了编译器错误——我没想到会出现这种随机行为。我会赞成答案。如果您想编辑您的答案以使其与“实际”解决方案相关,我也会将其标记为答案。感谢您的帮助!
    • 我已将真正的问题添加到答案中。您可以通过添加-Wall 标志使编译器对代码质量更加挑剔,并通过-Werror 要求它将警告视为错误。对于新代码来说,这确实是一个不错的选择,但是当警告是由您使用的第三方库引起时,就会很痛苦。
    猜你喜欢
    • 1970-01-01
    • 2015-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-09
    • 2011-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多