从命令行运行到“无需调试运行”的不同行为

时间:2011-03-18 13:37:50

标签: c++ visual-studio-2010 debugging

在这里抓我的头:我有一个应用程序在Debug + Release中可以正常工作,如果从Visual Studio 2010启动,在Debug和“Run without Debugging”中都可以。如果我从命令行运行相同的应用程序,使用相同的设置,我会看到不同的行为。特别是,运行方式不同的代码是:

const List& vl = nDesc.Get<List> ("slots");

int index = 0;
for (auto it = vl.begin (), end = vl.end (); it != end; ++it)
{
    desc.units [index++] = Parse (Tree (*it));
    // If I access it again here, e.g.
    // Log::Info (std::distance (vl.begin (), it))
    // this works always
}

我认为这是竞争条件,但代码完全是单线程的。有趣的是,添加一些随机代码并不能使它工作(即只记录一个字符串是不够的。)哦,这个循环只运行一次。

desc中的数据是相同的,在循环显示已写入相同数据后将其转储到文件中。在这段代码中上下移动循环无济于事;也没有将auto更改为List :: const_iterator帮助。

任何想法从哪里开始调试?

[更新]禁用此功能的优化不会修复Release,但我可以附加调试器并看到其中的所有内容都按预期工作。但我没有得到正确的程序行为。剧照也适用于“Run without Debugging”和“Run with Debug”。

2 个答案:

答案 0 :(得分:4)

我怀疑这个问题与未初始化的堆内存块有关。

在没有调试的情况下启动它并将其附加到调试器并从调试器启动它之间的主要区别在于,在第二种情况下使用Windows调试堆。

Windows Debug Heap使用特定模式(0xBAADF00D IIRC)预先填充传递给客户端的内存,并且只要连接了调试器启动可执行文件,就会激活它。即使它使未初始化的内存错误发现更容易(因为它用“奇怪”模式填充内存),在这种情况下可能它掩盖了你的问题,因为它只有在没有使用调试堆时才变得明显(所以未初始化)内存块可能用零填充。

请注意,这个特定的代码块可能只是冰山一角,问题可能源于不同的位置而且只是出现在这里。

找到这个错误的好运,我和第三方图书馆发生了这种确切的问题,尽管经过了几天的搜索,我不得不放弃。

(顺便说一下,Windows Debug Heap与CRT Debug Heap无关,而是仅在可执行文件的Debug版本中激活,而IIRC,它用0xCD模式填充内存)

答案 1 :(得分:0)

看起来desc.units没有足够的空间容纳所有添加到其中的项目,尽管我们需要更多的上下文来确定。