2010-09-02 17 views
26

使用Visual Studio,在附加到進程並按暫停(全部中斷)之後,切換到所需的線程並使用快速監視窗口檢出一些數據,如在暫停和'無法評估表達式'的情況下進行調試

MySingletonClass.Instance.Data 

有時我要麼得到這樣的:

因爲當前線程處於睡眠無法計算表達式,等待,或加入

或此(試圖查看數據的某些屬性時):

無法評估表達式,因爲本機幀位於調用堆棧之上。

非常坦率地說,我不在乎,我只是想看到數據!我知道有不同的方法來解決這個問題,即:

  1. 設置線程斷點和等待,直到它被擊中(繁瑣,並不總是可能的)
  2. 拍攝過程和裝載的轉儲回到VS(即使這樣我仍然得到第2次故障)
  3. 的WinDbg

給你可以看到這個數據,如果你大概使用的WinDbg它爲什麼大家都不能採取的更容易的優勢,更漂亮的VS來檢查物體時連接到一個進程?

回答

21

爲什麼我們不能這樣做?我們不能這樣做,因爲Visual Studio監視窗口不只是從內存中檢索數據並顯示它。它實際上執行託管代碼(這就是「評估表達式」的意思)。特別是,它幾乎總是執行ToString()方法來顯示用戶可讀的結果。

問題的關鍵是它在您正在調試的進程/線程內執行此代碼。這可以確保表達式的計算方式與實際在您正在調試的代碼中執行的方式相同。這樣做的缺點是它只能在託管指令之間執行,而不能在本機代碼處於活動狀態時執行,而不能在阻塞的線程中執行。

我們能做些什麼呢?如果您實際上正在調試託管應用程序,並且您處於本機堆棧中,只需重複按F10或Shift + F11,直到您重新進入托管代碼。然後你可以評估表達式。但是,對於完全本機進程以及處於阻塞狀態的線程,我不知道任何解決方法。

3

只需點擊Shift-F11,直到堆棧頂部有一個託管堆棧框架,您就可以在VS中執行所需操作。

它基本上歸結爲這樣一個事實,即在流程執行期間在某些點評估表達式並不安全,否則可能會損壞運行時。 WinDbg不保護您的運行時間。 VS的確如此。

+1

在大多數情況下,我所看到的是由於長時間運行的方法,例如SQL查詢。 – leppie 2010-09-02 12:03:49

2

問題是,那不是你想看到的數據,而是運行一些代碼的結果。 .Net屬性實際上只是僞裝的方法,所以爲了獲取屬性的值,Visual Studio需要執行應用程序代碼(該功能稱爲FuncEval)。

此代碼必須在某個線程上運行,VS所做的是使用其中一個應用程序線程。有a number of situations其中VS無法運行代碼以產生結果,那是當你看到你正在談論的錯誤消息。

+0

謝謝,這清除了一些東西,但是當我拿到轉儲文件時,我無法看到數據,例如Load Dump文件,切換到'睡眠'線程,並快速觀察'this'和數據出現。 – wal 2010-09-02 12:29:05

+0

by'shows up'我的意思是我沒有得到'無法評估表達式,因爲當前線程處於睡眠,等待或加入' – wal 2010-09-02 12:38:26

0

如果您繼續下一條指令,調試器可能有足夠的時間在超時之前對其進行評估。

請注意,這不會總是工作。

4

這是一個link來討論這個問題。顯然,當函數參數是結構體時,堆棧上調用該函數所需的總內存超過了一些不可思議的數字visual studio調試器pukers。

來自OpenTK框架討論的其他link

0

如果你的項目的客戶端服務器,請嘗試重新上傳參考MySql.Data.dll

0

我知道這是個雜牌,但我很高興與它的工作方式。在我的Main()方法,最初開始的一切,並創建所有其他的數據結構和線程,然後終止結束,我堅持這一點:

 while (true) 
     { 
      // This infinite while loop just gives me a convenient place for a 
      // breakpoint, so I can see everything everywhere during debugging. 
      Thread.Sleep(100); 
     } 

而不是做一個的「打破一切」我只是堅持一個在大括號{}上的斷點。程序中斷。我有一個可用的線程和一切的參考,所以我可以輕鬆瀏覽所有數據結構和所有線程,查看所有地方。