2011-03-18 61 views
3

在這裏抓我的腦海:我有一個應用程序,在調試和「無需調試運行」的情況下,如果從Visual Studio 2010啓動,在Debug + Release中工作正常。如果我使用相同的設置從命令行運行相同的應用程序,我會看到不同的行爲。特別是,運行不同的代碼是:從命令行運行到「無需調試運行」的不同行爲

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中的數據是相同的,在循環顯示相同的數據被寫入後,將其轉儲到文件。在這段代碼中上下移動循環並沒有幫助;也不會將自動更改爲List :: const_iterator幫助。

任何想法開始調試呢?

[更新]關閉此功能的優化功能並不能解決發佈問題,但我可以附加調試程序並查看其中的所有內容都按預期工作。但我沒有得到正確的程序行爲。 Stills可以在「無需調試運行」和「與調試一起運行」的情況下使用。

+0

如果你開始它沒有調試,並且稍後附加調試器會出現錯誤嗎? – 2011-03-18 13:42:45

+0

是的,似乎是這樣。有趣的,讓我們看看是否有幫助。 – Anteru 2011-03-18 13:45:23

+0

這不一定與這段代碼有任何關係 - 它可能會覆蓋此代碼使用的內存。 cmd vs VS最大的區別是環境,路徑和命令行參數 - 檢查這些 – 2011-03-18 13:45:51

回答

4

我懷疑問題與未初始化的堆內存塊有關。

啓動它而不進行調試並將其附加到調試器並從調試器啓動它的主要區別在於,在第二種情況下使用了Windows調試堆。

Windows調試堆預填充交給客戶端的內存以特定模式(0xBAADF00D IIRC),並且每當使用附加的調試器啓動可執行文件時,它就會被激活。即使使未初始化的內存錯誤發現變得更容易(因爲它會用一種「奇怪的」模式填充內存),在這種情況下,它可能掩蓋了您的問題,因爲只有在未使用調試堆時才顯而易見(因此未初始化內存塊可能充滿了零)。

請注意,這個特定的代碼塊可能只是冰山一角,問題可能起源於不同的位置,只是在這裏出現。

祝你好運,找到錯誤,這種確切的問題也發生在我身上,第三方庫,儘管有幾天的搜索,我不得不放棄。

(順便說一句,在Windows調試堆是從CRT調試堆無關,那不是被激活僅在調試版本的可執行文件,並且,IIRC,它填補與0XCD模式內存)

+0

注意從VS開始_without_調試時,我會得到正確的行爲。 – Anteru 2011-03-18 13:51:06

+0

@Anteru:沒有什麼奇怪的,一旦我偶然發現完全相同的問題(確定調試堆,崩潰在「正常」堆上)。這取決於哪種模式(0xBAADF00D/0xCD/0x00)更可能導致代碼失敗。 – 2011-03-18 13:57:35

+0

所以,即使我沒有從VS內部調試運行,我會得到調試堆? – Anteru 2011-03-18 16:45:19

0

它看起來像desc.units沒有足夠的空間來添加所有項目,雖然我們需要更多的上下文來確保。

+0

使用desc.units.at(index ++)不會引發異常,所以沒關係。它已預先填充到其他地方的正確金額。 – Anteru 2011-03-18 13:51:36