2

What is the best and easiest method to debug optimized code on Unix which is written in C?

Sometimes we also don't have the code for building an unoptimized library.

4

3 回答 3

3

这个问题问得好。过去我也遇到过类似的困难,我必须在我的应用程序中集成 3rd 方工具。根据我的经验,您需要在关联的符号文件中至少有有意义的调用堆栈。这只是地址和相关函数名称的列表。这些通常会被剥离,仅从二进制文件中您将无法获得它们...如果您有这些符号文件,则可以在启动gdb时加载它们,或者随后通过添加它们。如果没有,您将被困在装配级别...

一种奇怪的行为:即使你有源代码,它也会在你意想不到的地方来回跳动(语句可能会重新排序以获得更好的性能)或变量不再存在(优化掉!),在内联函数中设置断点是没有意义的(它们不存在,而是它们被内联的地方的一部分)。所以即使有源代码,也要注意这些陷阱。

我忘了提,符号文件通常有扩展名.gdb,但它可以不同......

于 2009-10-12T11:07:26.933 回答
2

这个问题与“修理乘用车的最佳方法是什么?”没有什么不同。

在 UNIX 上调试优化代码的最佳方式取决于您拥有的 UNIX、可用的工具以及尝试调试的问题类型。

调试崩溃malloc与调试unresolved symbol at runtime.

对于一般调试技术,我推荐这本书

有几件事会使在“装配级别”的调试变得更容易:

  • 你应该知道你的平台的调用约定,所以你可以知道什么值被传入和返回,在哪里可以找到 this指针,哪些寄存器是“调用者保存的”,哪些是“被调用者保存的”,等等。
  • 你应该知道你的操作系统“调用约定”——系统调用是什么样的,系统调用号进入哪个寄存器,第一个参数等等。
  • 您应该“掌握”调试器:知道如何查找线程、如何停止单个线程、如何在单个指令上设置条件断点、单步执行、单步执行或跳过函数调用等。

它通常有助于“并行”调试工作程序和损坏的程序。如果 1.1 版有效而 1.2 版无效,那么它们在特定 API 方面的分歧在哪里?在调试器下启动两个程序,在同一组函数上设置断点,运行这两个程序并观察在哪些断点被命中以及传递了哪些参数方面的差异。

于 2009-10-13T13:25:06.643 回答
0

通过相同的接口(在其标头中)编写小代码示例,并调用您的示例而不是优化的代码,例如模拟,以缩小您调试的代码范围。此外,您可以在样本中进行错误注入。

于 2009-10-12T11:21:16.930 回答