0

我一直在追查似乎是由于内存损坏造成的崩溃。设置为 C,使用 llvm for iOS 构建。

在调试模式和优化级别 0 (-O0) 中不存在内存损坏。为了能够单步执行代码,我使用调试符号进行了重建,但优化级别为 1 (-O1)。这足以重现崩溃,它允许我逐步完成程序。

我已将问题缩小到特定的函数调用。在它之前,某个指针的值是正确的。在它之后,值被破坏(它最终等于 0x02,无论它是什么值)。

Lldb 似乎不想查看变量或内存位置。切换到 gdb,我发现如果我尝试打印上述变量的地址,我会遇到以下消息:“地址请求标识符'x',它在寄存器 $r4 中”。

我知道,作为一种优化,编译器可能会决定将变量的值保存在寄存器中。确实,如果我在函数调用之前和之后打印 $r4 的值,我会在之前和之后看到正确的值和 0x02。

在这一点上,我有点不知所措,不知道如何将其分解为更小的问题。因此,我的问题是:

  1. 假设编译器将变量的值存储在寄存器中作为优化,那么当调用另一个函数时该寄存器应该发生什么?

  2. 是否有某种机制可以在新函数返回后存储和恢复值?

  3. 关于调试技术的任何建议?

所有帮助和建议表示赞赏。也非常欢迎提供有关该主题的阅读材料的链接。

谢谢


编辑:添加版本信息

iOS版本:5.1

llvm 版本:i686-apple-darwin10-llvm-gcc-4.2 (GCC) 4.2.1(基于 Apple Inc. build 5658)(LLVM build 2377.00)

Xcode 版本:4.3.1

gdb 版本:GNU gdb 6.3.50-20050815(苹果版 gdb-1708)

在 iPhone 3Gs 上运行(模拟器中不会出现崩溃)

4

2 回答 2

0

不是完整的答案,但是

假设编译器将变量的值存储在寄存器中作为优化,那么当调用另一个函数时该寄存器应该发生什么?

寄存器可能应该由被调用者推入堆栈。

是否有某种机制可以在新函数返回后存储和恢复值?

取决于调用约定,但通常 - 将其推入堆栈的人负责将其从堆栈中弹出

最后一件事:

如果您遇到这种情况,在某些优化级别上“它有效”而在其他优化级别上无效,那么您很可能会有未定义的行为。如果你在你的代码中找不到它,你可以在这里问它,给出实际的代码。

于 2012-05-04T13:51:59.407 回答
0

如果可能,请尝试使用 Valgrind。看起来是一个很好的起点。

另外,尝试为您的程序启用 -fstack-protector。

于 2012-05-04T14:00:39.097 回答