我经常在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脚本。加载单个线程可执行文件,设置断点,符合可执行文件并在达到断点后打印变量值的最小示例对我来说非常有用。
答案 0 :(得分:0)
如果在示例中打开优化并且参数是代码中的常量,我希望编译器完全正确,并简化整个事情以返回预先计算的5的平方根。
市场上有一些产品可以进行“代码流分析”,并且可以理解边界条件,“如果使用负值调用sqrt,那就是错误”等等。 Coverity是一个(不是任何接近免费的)工具,可以在C / C ++上执行此操作,并吐出“你正试图在这里做些蠢事,你确定这是对的吗?”输入代码的消息。
Valgrind也可以做类似的事情。
但是这些工具都不能为一组代码运行注释变量的当前值。这样做是可能的,但与全速运行代码相比,这将是相当耗时的,并且如果代码是运行几次迭代的任何超过几百行,那么它可能需要几乎永远并且产生发生了什么事的非常大的日志文件。根本不相信它是实用的。
答案 1 :(得分:0)
你可以采用不同的方式:
创建一个日志文件(可以通过printf完成并在运行时重定向标准输出)。您可以打印感兴趣的值和diff
来自不同运行的两个日志。