比较不同输入下相同代码的执行路径

Posted

技术标签:

【中文标题】比较不同输入下相同代码的执行路径【英文标题】:Compare execution paths of same code under different inputs 【发布时间】:2012-12-09 19:33:24 【问题描述】:

我正在调试一个非常复杂的 C++ 函数,它在某些输入下会给我一些意想不到的结果。我想比较不同输入下的代码执行情况,以便找出导致我出错的部分。 可以比较代码执行路径的工具是我正在寻找的。请让我知道是否存在这样的工具。或者如果有一些技术我可以用来做同样的事情?

为了具体描述我的问题,这里我使用一个人为的例子。

说这是伪代码中的函数,

double payTax(double income)

   if (income < 10000)
      return noTax();
   else if ( 10000 < income < 30000)
      return levelOneTax();
   else if (30000 < income < 48000)
      return levelTwoTax();
   else  
      return levelThreeAboveTax();

给定输入 15000,该函数计算正确的税额,但不知何故,输入 16000 给出了错误的税额。假设输入 15000 和 16000 会导致函数通过完全相同的执行路径;另一方面,如果它们走不同的路径,那么函数中一定有问题。因此,比较执行路径的工具会揭示足够的信息,帮助我快速识别错误。我正在寻找这样的工具。最好与Visual Studio 2010兼容。如果这样的工具还保留变量的值会更好。

附:调试是我最不想做的事情,因为我正在使用的代码库比简单的 payTax 示例要大得多且复杂得多。

请帮忙。谢谢。

【问题讨论】:

您是否已启动并运行 Visual Studio 2010?如果是这样,您是否尝试在函数payTax() 的开头放置断点,然后在调试器中运行程序? 是的。正如我所说,真正的功能比人为的例子复杂一千倍。我可以使用调试器,但与拥有这样的工具相比,它会花费我更多的时间。 @丹尼森鲍姆 如果没有完整的细节,很难给出一个好的答案,但调试器所做的不仅仅是基本的断点和单步执行。您可以使用条件断点来跟踪执行何时以给定的前提条件意外结束。对于您的示例,断点只能在给定的输入范围内触发。 @Shuo 我也一直在寻找这样的工具(虽然适用于.NET/C#),会发现它最有帮助!你有没有找到任何工具或替代解决方案? 【参考方案1】:

您要查找的关键字是“代码覆盖率”或“覆盖率分析”或“代码覆盖率分析”。

您使用哪种工具自然取决于您的其他环境。

【讨论】:

谢谢。我也知道代码覆盖率,但我自己并没有真正使用过任何代码覆盖率工具。你介意分享一个已经成功测试和使用的工具吗?【参考方案2】:

您要的工具是printfstd::cerr

您的代码中有一个严重错误:像if ( 10000 &lt; income &lt; 30000) 这样的语句将无法按预期工作!你想写成if( 10000 &lt; income &amp;&amp; income &lt; 30000 )

为了保持测试简单,请使用大括号,如下所示:

if( 10000 < income && income < 30000 ) 
    return levelOneTax();
 else if( ...

因为这样添加调试输出会容易得多,如下所示:

if( 10000 < income && income < 30000 ) 
    std::cerr << "using levelOneTax for income=" << income << std::endl;
    return levelOneTax();
 else if( ...

编辑

顺便说一句:“一个比较执行路径的工具会揭示足够的信息 [...]”,但是在您所期望的意义上,这样的工具会揭示太多需要处理的信息。您能做的最好的事情是调试并验证您的代码是否按照您的预期进行。对于您的情况,“代码覆盖率”工具可能太大(而且此类工具也不便宜)。

【讨论】:

代码风格和语法正确性在这里不是问题,因为我只是以此为例。 printf 和 std:cerr 太费劲了,因为我有这么大的代码库,而且我对代码本身并不熟悉。 嗯,我认为你的意思是代码覆盖工具对我来说太大了。但我正在寻找一种更简单的方法,它只给出两次执行的差异,这就是我所需要的。 另一个想法:尝试使用类似于“单元测试”的功能,并记录一系列输入的输入和输出。 是的,AFAIK 当前可用的代码覆盖率工具对于您的用例来说太大了。

以上是关于比较不同输入下相同代码的执行路径的主要内容,如果未能解决你的问题,请参考以下文章

加密算法在linux下相同输入每次加密结果都不同的问题

输入长度受限情况下的 XSS 攻击

Elasticsearch启动https

在 Core ML 中使用 MLClassifier 始终为不同的输入获得相同的预测

汇编实验三

相同输入的 ideone 和代码块中的不同输出(小阶乘)