【发布时间】:2011-12-20 20:47:17
【问题描述】:
首先,一些背景知识:我们有一个框架将多次运行一系列测试,并确保每次运行时的状态相同。这捕获了许多产生不确定行为的情况,包括由多线程或指针值排序引起的情况。这些测试在 Visual Studio 2008 上的 Debug 中运行(即将移至 2010 年)。
问题:不幸的是,测试并没有像我希望的那样经常捕捉到未初始化变量的使用。考虑以下情况:
struct Foo{ int m_a; int m_b; };
void doStuff( struct Foo& f);
...
Foo* bar = new Foo();
// Uninitialized in ctor, but heap initialized to 0xCD,
// so appears "deterministic"
if (bar->m_a)
{ ... }
Foo baz;
// may or may not initialize all of baz
// uninitialized members are left to 0xCC
doStuff( baz );
if (baz.m_b)
{ ... }
我想做的是在每次运行时使未初始化的值不同以捕获这些情况,例如第一次运行时已知垃圾,第二次运行时为 0。这样,对未初始化成员的任何计算都会给出不同的结果,并且在 if 语句中检查它们也将采用相反的分支。
我可以控制第一种情况,因为我们通过自己的堆路由 new 和 delete。但是,我无法找到有关如何控制堆栈变量的填充值的任何信息 - 这可能吗?我可以在这里找到的最接近的问题是Can g++ fill uninitialized POD variables with known values?,但这是针对 g++ 的。我不需要便携式解决方案;一个特定于 Visual Studio 的技巧就可以了。
注意 #1:我知道 lint/Rational Purify/Valgrind/[insert static code analysis magic bullet] 会捕捉到这一点,而且可能更健壮。但我正在寻找可以对现有框架进行的小改动,这些改动可能需要比我准备花费更多的时间来集成,所以请不要建议这些。
注意 #2:我们已经将警告级别设置为最大值并在打开错误时发出警告,这会捕获一些未初始化变量的情况,但这并不能捕获“doStuff”函数忘记初始化的所有情况一些结构。
注意 #3:我不太担心性能,因为它已经在 Debug 中运行,并且仅用于内部测试。
注意 #4:相同的可执行文件用于测试(在“写入”模式下运行一次,然后在“检查”模式下再次运行以比较结果),因此很遗憾,目前无法选择不同的编译设置。
提前致谢!
【问题讨论】:
-
更改它不是一种选择。导致不匹配的一个明显方法是将 Debug 构建的结果与没有 /RTC 生效的构建进行比较。就像发布版本一样,真正需要测试的版本。
-
系统当前的结构是相同的可执行文件运行每个测试。我应该在之前提到过。
-
给所有东西一个默认构造函数,将每个成员设置为
MAGIC_VAL不是最简单的吗?并使用设置为不同值的MAGIC_VAL进行几次调试测试。 -
或者,/RTC1 flag
-
@MooingDuck - 看起来 /RTC1 仍然遗漏了一些基本案例。它是否捕捉到了 4 级警告(我们已经拥有)没有捕捉到的任何东西?
标签: c++ visual-studio visual-c++ memory