1

我经常在 C 中调试数值例程。这意味着我使用 gdb 运行程序并单步执行要调试的函数。然后我通过使用 gdb 打印变量来将数值与我的期望进行比较。显然,这个过程对于较长的例程来说是乏味的。特别是,如果我更改例程并想与以前的结果进行比较,我需要记住后续运行之间不同变量的值。在某些情况下,如果我有一个工具可以自动将变量替换为执行期间遇到的数值,这将有很大帮助(特别是如果例程或多或少是线性的)。例如一个简短的(琐碎的)示例例程

myfunc(double a, double b)
{
  double tmp_a, tmp_b, c;

  tmp_a = a*a;
  tmp_b = b*b;

  c = sqrt(tmp_a+tmp_b);

  return c;
}

可以转换为

myfunc(double a<1.0>, double b<2.0>)
{
  double tmp_a, tmp_b, c;

  tmp_a = a<1.0>*a<1.0>;
  tmp_b = b<2.0>*b<2.0>;

  c = sqrt(tmp_a<1.0>+tmp_b<4.0>);

  return c<2.236067977499789696e+00>;
}

我可以使用 diff 工具轻松比较后续运行的输出。我还可以通过将输出粘贴到计算机代数系统中来将中间数值结果与任意精度结果进行比较。粗略的想法是,gdb驱动程序执行二进制文件直到指定的例程,逐步执行它(每次将一步中的所有变量替换为当时各自的值)并最终退出。非常欢迎对现有软件或实现想法的提示。也许有一个基于 perl 的解决方案,使用现有的 gdb 接口,例如Devel::GDB(不确定这个是否足够成熟)。


似乎从版本 7 开始 gdb 支持 python 脚本。一个加载单线程可执行文件、设置断点、运行可执行文件并在达到断点后打印变量值的最小示例对我来说真的很有帮助。

4

2 回答 2

0

您可以采用不同的方式:
创建一个日志文件(可以通过 printf 完成并在运行时重定向标准输出)。您可以打印感兴趣的值和diff来自不同运行的两个日志。

于 2013-02-20T12:54:47.433 回答
0

如果您在示例中打开优化并且参数是代码中的常量,我希望编译器会这样做,并简化整个事情以返回预先计算的 5 平方根。

市场上有一些产品可以进行“代码流分析”并且理解边界条件和“如果使用负值调用 sqrt 是错误的”等等。Coverity 是一个(不是免费的)工具,它在 C/C++ 上执行此操作,并吐出“你在这里试图做一些愚蠢的事情,你确定这是对的吗?” 为您的代码键入消息。

Valgrind 也可以做类似的事情。

但是这些工具都不能为一组代码运行注释变量的当前值。这是可能的,但与全速运行代码相比,它会相当耗时,而且如果代码超过几百行运行几次迭代,它可能会花费几乎永远并产生一个非常大的日志文件,记录了在哪里发生的事情。完全不相信它是实用的。

于 2013-02-20T12:47:13.163 回答