查找嵌入式C语言程序/软件中的缺陷的多种技术
finalize()函数先于printMessage()函数被调用,但是finalize()函数中释放了printMessage()函数需要使用的内存。
void finalize()
{
if (messages) {
free(messages[0]);
free(messages[1]);
free(messages[2]);
}
free(messages);
}
将函数调用顺序进行修改后,我们重新运行程序。
这样我们就解决了上面报告中的第一个错误。现在我们再来分析报告中的第二个错误:即打印信息中的AccessViolatiONException。产生这个错误的原因是相应的消息列表未经初始化。为了解决该问题,我们在打印该信息前调用一次initialize()函数来对其进行初始化。经修改后的函数如下所示:
1/3 123下一页尾页
void reportSensorFailure()
{
initialize();
printMessage(ERROR, 0);
finalize();
}
当我们再次运行该测试用例时,仅有一个任务被报告出来:未经验证的单元测试用例一体成型电感 (an unvalidated unit test case),这其实并不算一条错误。我们只需对输出进行一下验证,以将该测试用例转换为回归测试。通过创建合适的断言,C++test会自动为我们完成这些步骤。
接下来我们再次运行整个程序。覆盖率分析告诉我们几乎整个程序都已经被覆盖到了,并且没有发现任何内存错误。
这样就结束了吗?其实不然。虽然我们运行了整个程序并为未覆盖到的函数创建了单元测试用例,但还是有一些路径是没有被覆盖到的。我们仍然可以继续创建单元测试用例,但是若指望通过这样的方法来覆盖程序中的所有路径将耗费相当长的时间。或者我们使用另外的方法,使用数据流分析来对这些路径进行模拟。
数据流分析
我们使用C++test的BugDetective来进行数据流分析,BugDetective能模拟系统中的不同路径并检查这些路径中是否存在潜在的问题。进行数据流分析后,我们得到如下结果: