有没有办法比较两个不同的C/C++程序运行?

hig*_*241 6 c c++ debugging gdb valgrind

所以我正在调试这个程序,这个程序是我从即将毕业的博士生中继承的,或者是在学生完成论文后发生的任何事情.无论如何,现在我有责任进行调试.该程序基本上接受几个文本文件并处理它们.我遇到的问题(段错误)是因为程序试图访问尚未初始化的数组.我想知道是否有任何调试工具可以让你运行程序,并比较程序关闭的两个不同路径.我想我可以手动完成程序,但我宁愿不这样做,因为它相当大,我仍然没有掌握它.我一直在使用GDB和Valgrind(以及使用g ++ -wall来显示警告),这就是我如何做到这一点.

jxh*_*jxh 5

这些建议是针对 GCC 的。您可以使用gcov覆盖率工具详细了解程序的哪些部分已执行以及执行频率。您必须将一些特殊选项传递给 GCC 以生成适当的检测和输出以gcov进行处理。

--coverage 此选项用于编译和链接用于覆盖分析的代码。该选项是-fprofile-arcs -ftest-coverage(编译时)和-lgcov(链接时)的同义词。有关更多详细信息,请参阅这些选项的文档。

然后,当您执行程序时,会生成一些分析和覆盖数据。然后您可以调用gcov以分析该输出。下面是从上面的链接中获取的输出示例:

         -:    0:Source:tmp.c
         -:    0:Graph:tmp.gcno
         -:    0:Data:tmp.gcda
         -:    0:Runs:1
         -:    0:Programs:1
         -:    1:#include <stdio.h>
         -:    2:
         -:    3:int main (void)
         1:    4:{
         1:    5:  int i, total;
         -:    6:
         1:    7:  total = 0;
         -:    8:
        11:    9:  for (i = 0; i < 10; i++)
        10:   10:    total += i;
         -:   11:
         1:   12:  if (total != 45)
     #####:   13:    printf ("Failure\n");
         -:   14:  else
         1:   15:    printf ("Success\n");
         1:   16:  return 0;
         -:   17:}
Run Code Online (Sandbox Code Playgroud)

如果要实现自己的检测来记录程序的调用历史记录,可以使用-finstrument-functionsGCC 上的 及其相关选项。

-finstrument-functions
生成用于进入和退出函数的检测调用。在函数进入之后和函数退出之前,使用当前函数的地址及其调用点调用以下分析函数。(在某些平台上,__builtin_return_address在当前函数之外不起作用,因此调用站点信息可能无法用于分析函数。)

      void __cyg_profile_func_enter (void *this_fn,
                                     void *call_site);
      void __cyg_profile_func_exit  (void *this_fn,
                                     void *call_site);
Run Code Online (Sandbox Code Playgroud)

第一个参数是当前函数的起始地址,可以在符号表中准确查找。

在 C++ 中,这些钩子的实现应该声明为extern "C". 您可以实现钩子以在每次调用函数时记录日志。您不会获得函数名称,但您可以在之后使用objdump或对指针进行后期处理addr2line


Joh*_*han 4

我认为您选择 GDB 和 valgrind 等工具的方向是正确的。

使用 GDB,您可以在两种情况下编写程序执行脚本,并在发生段错误时查看调用堆栈。然后,您可以在该位置放置一个断点,并使用不会使程序崩溃的参数再次运行,并调查两者之间的差异。

使用 valgrind,它实际上是一套工具 ( http://valgrind.org/info/tools.html ),您可以使用 callgrind 和 kcachegrind 取得一些成功。Callgrind 为您提供调用图,而 kcachegrind ( http://kcachegrind.sourceforge.net/cgi-bin/show.cgi/KcacheGrindIndex ) 允许您将它们可视化。我将它们用于大型 C 代码库的性能分析。

另一个可以帮助您的工具是 Fenris ( http://lcamt​​uf.coredump.cx/fenris/whatis.shtml ),它也可以打印出代码的调用图。在阅读您的要求时,我认为 Fenris 最接近,因为它还允许您“可视化”所采用的代码路径。