2010-09-21 87 views
3

我正在用Visual Studio調試C/C++代碼。有一個稱爲10000次的循環,在循環結束時,在一次交互中,出現錯誤,因爲程序試圖訪問長度爲N的數組的N + 1值。我想返回並調試錯誤的來源,我想知道在調試模式下,Visual Studio是否可以直觀地突出顯示或告訴我源代碼的哪一行被執行。那麼找到這個錯誤會更容易。有誰知道這是否可能?是否有可能知道源代碼的哪一行被執行?

如果這對於VS來說是不可能的,還有什麼其他方法可以做到這一點?

感謝

編輯:我也想知道這可能是與任何其他的IDE(Eclipse中,Xcode中,命令行等)

回答

1

我不知道任何這樣的工具,而是一個替補來完成將是在每個條件內打印不同的消息。

if(somethingThatMightNotHappen) { 
    printf("This happened.\n"); 
    ... 
} 
+0

但如果你有10000行代碼,這是不實際的。如果至少有一個可以自動生成... – flow 2010-10-11 10:58:19

1

不,VS調試器不允許你隨時間倒退。

但是,看看有條件的斷點。當循環運行第N(或第N-1次或其他)時間或滿足特定條件(如變量idx > 1000)並逐步執行代碼時,您可能會中斷。

+1

實際上我認爲它在vs2010中有效;但我不確定它支持哪些語言http://msdn.microsoft.com/en-us/magazine/ee336126.aspx – pm100 2010-09-21 17:33:47

+0

@ pm100:哇,有趣的閱讀!我還沒有時間玩VS2010。 – sbi 2010-09-21 17:43:50

+0

你可以用'record','rs'和'rn'來使用GDB。 – alternative 2010-09-21 21:22:07

9

在發生數組訪問的地方放置了一個條件斷點。這樣,您的程序將在第N + 1次訪問時中斷,並且您將擁有完整的堆棧跟蹤。

+1

我建議每個開發人員花半個小時來研究它們使用的調試器的功能(例如,按照Sridhar Iyer的建議在斷點上添加條件)。但是,當我觀察我的同事時,我發現他們添加了用於調試的打印語句並浪費了大量時間。我只是不明白它... – Codo 2010-09-21 19:21:25

+2

@Codo - 打印語句是一個非常寶貴的調試工具,我很熟悉VS調試器,Windbg和在大學裏使用gdb相當多,但我仍然多次使用打印語句進行調試。奇怪的是,在閱讀「編譯器」一書時(參見http://www.codersatwork.com/),業內許多「精英」都表示很多時候他們只是使用打印語句進行調試。 – pstrjds 2010-11-09 15:04:08

+0

@Code我同意,但是找到一本能夠教你C++的好書比尋找教你好調試的書更容易 – nus 2010-11-10 21:16:06

0

如果設置了代碼分析在Visual Studio中,你可以配置它提供代碼覆蓋率信息,這將給一些你正在尋找的信息,但它不會幫助解決問題。

我會採取的做法是減少循環的計數到一個可管理的數字(比如說10)並逐步完成代碼。如果你知道你期望會發生什麼,那麼我發現,單步執行代碼並驗證它是否執行了你期望的一個小測試集的操作,可以澄清任何奇怪的行爲。

以我的經驗,沒有什麼比預測計算機會做什麼,然後驗證你都同意。最常見的原因是:

  • 你的條件是小於或等於代替小於
  • 您測試一個比你更希望
  • 你的陣列是一個比你小的期望
  • 你從1開始計數,循環遍歷元素數

off-by-one(後三個)只是算法中最常見的錯誤。

6

如果您知道需要進行多少次迭代(在本例中爲10,000次),那麼您肯定可以在循環中插入命中計數n(錯誤之前的一個),然後逐步執行下一步使用Intellisense進行迭代爲您提供有關可能導致問題的信息?

alt text

你有任何代碼,我們可以看到,可以幫助我們來幫助你?

0

單元測試框架將做你想要的。你需要創建一個運行你想調用的函數的單元測試。然後,編輯您的測試運行配置以啓用代碼覆蓋。

最後,一旦你運行了你的單元測試(它可以只是一行代碼來執行一個功能),轉到「代碼覆蓋結果」窗口並選擇「顯示代碼覆蓋顏色」選項。執行的代碼將以藍色標記,未執行的代碼將以紅色標記。

漂亮,呃?

更新爲了迴應有關C++的評論,我確信此功能可以與C++一起使用,但我從未使用它。嘗試右鍵單擊實現要測試代碼覆蓋的函數的代碼。應該有一個選項「創建單元測試」。在做這件事之前一定要編寫代碼。

+0

它使用C++嗎? – flow 2010-11-09 10:04:53

+0

查看我的更新回答 – 2010-11-09 14:57:24

0

試着抓住例外!只需將循環內的代碼放入一個try-block中,然後再加上一個帶有斷點的catch-block。

0

其中一些調試技術已經被提及,我不能保證所有的C++都能工作,但ScottGu在他的blog post中有很好的提示。

我想你已經知道這件事了,但對我來說聽起來就像你在調試模式下尋找調用堆棧標籤。您可以在循環中使用命中計數或條件調試模式,當出現錯誤時,您可以將調用堆棧放回數據所在的位置,並設置幾個斷點。然後,您可以再次運行您的程序並檢查數據的構建方式。

相關問題