本文章是由機器翻譯。

Visual Studio2015

使用 IntelliTrace 來更快地診斷問題

Angelos Petropoulos

當您在調試時,想想你典型的工作流。直到你成功地找出問題的根源,你被困在迴圈中設置中斷點和重複重現問題的測試步驟。您現在可以使用 IntelliTrace 到記錄歷史運行應用程式的調試資訊。這可以説明你打破這一迴圈。您可以執行一次測試的步驟來重現問題,然後使用歷史調試來找出其根源。

IntelliTrace 是集歷史的調試技術,擴展調試器在Visual Studio2015年企業。也是獨立的元件,您可以使用在Visual Studio的外部。IntelliTrace 記錄您應用程式的執行,尋找有趣的事件。有趣的事件發生時,IntelliTrace 自動記錄的呼叫堆疊和本地變數同時應用程式繼續運行。您可以控制的事件 IntelliTrace 認為"有趣"通過工具 |選項 |IntelliTrace |IntelliTrace 事件。

IntelliTrace 為您提供了您的應用程式執行使用時間線 (事件的高級別視圖) 和顯示每個事件的詳細資訊的表的歷史。它也賦予你訪問歷史調試資料通過擴展並結合Visual Studio調試器。這允許您選擇回到那個時間,看到呼叫堆疊和區域變數的收集的事件。

IntelliTrace 已在Visual Studio2015年診斷工具視窗中找到新家。 診斷工具視窗包含 CPU 使用率工具和記憶體使用方式的工具,以及 IntelliTrace。如果您的專案類型和調試配置支援 (最新的資訊,請查看 aka.ms/diagtoolswindow),你會看到出現當你開始在Visual Studio2015年調試診斷工具視窗 (你可以按 f5 鍵或您始終可以打開它手動使用 Debug |顯示診斷工具)。當你啟動歷史調試時,您會看到類似于圖 1

歷史的調試器調試
圖 1 歷史的調試器調試

探討 UI

以下是每個元件的 IntelliTrace UI 和其預期的目的和功能的清單:

調試器事件:調試器事件詳細資訊表 (見圖 2) 是表格視圖的 IntelliTrace 已收集的事件。從左至右的列有:

  1. 一個指標,指向該事件的調試器當前正在顯示的資訊 ; 只包含一行將黃色箭頭指示當前指令指標的位置和一行可能有粉紅色的箭頭,表明您已經啟動了哪些歷史事件。
  2. 用來表示此事件調試器事件時間表上的圖示。
  3. 事件的簡短說明。
  4. 秒數從調試會話開始收集事件的時間。
  5. 該事件的持續時間。(注意:並不是所有的事件有一個持續時間)。
  6. 執行緒 ID 和建置事件的名稱。(注意:並不是所有的事件都與執行緒關聯)

調試器事件表
圖 2 調試器事件表

如果你點擊一個事件清單,將其展開,然後可以選擇啟動歷史調試並將調試器設置為在哪裡 IntelliTrace 記錄所選的事件的點。

類別篩選控制項:此篩選控制項允許您隱藏或顯示的事件類別,而他們仍會被收集。如果你想要把重點放在某一特定類別或你在另一個完全不感興趣,你可以使用這,迅速使其進入視野並從。當前類別清單包括:ADO.NET、ASP.NET、 主控台、 資料繫結、 調試器、 環境變數、 異常、 檔、 手勢、 延遲初始化、 輸出、 註冊表服務模型中,執行緒,追蹤、 使用者提示和 XAML。

執行緒篩選器控制:此篩選控制項允許您隱藏或顯示從中產生,你只是感興趣診斷特定執行緒或你積極執行特定執行緒已沒有問題的情況下,執行緒的事件。

從外部代碼按鈕顯示的事件:IntelliTrace 尊重調試器僅我的代碼設置。這意味著,預設情況下,它隱藏事件起源于非使用者代碼,以減少雜訊。點擊這將繞過調試器的設置並顯示來自外部代碼的事件。大多數情況下,這將導致詳細輸出。

調試器事件時間表:這是隨著時間的推移,IntelliTrace 已收集的事件的圖形視圖。這是事件詳細資訊表中所示的相同資訊的不同視圖。使用時間軸來獲得高級別視圖,和確定並選擇你想要鑽入與事件詳細資訊表視圖的區域。您可以篩選你看到的事件的詳細資訊表視圖中通過選擇某個特定時間範圍。

尺規:時間軸中,上面有一把尺子,顯示你在每個事件的發生的時間點。它還允許你通過點擊和拖動來選擇某個特定時間範圍。選擇要篩選調試器事件詳細資訊表的時間範圍。

中斷事件跟蹤:每一次突破相關的事件發生時,似乎在這個時間表軌上。中斷的事件都命中中斷點、 已完成的步驟,按一下全部中斷,調用 Debugger.Break 或未處理的異常中斷執行。認為這是主時間軸軌道,以説明您東方其他軌道的事件發生在該程式的執行 (因為使用中斷點和步驟是,你怎樣控制您的應用程式執行)。按一下事件在這條賽道上的適用時間篩選器,將篩選調試器事件詳細資訊表中的事件。這種方式,您可以輕鬆地篩選僅對那些事件發生當你跨過線之間您按 f5 鍵並命中中斷點或代碼。

輸出的事件跟蹤:這條賽道將顯示在輸出視窗中顯示的消息的事件。出現在這條賽道的事件類別是:拋出的異常,程式輸出 (或 Console.WriteLine),模組載入/卸載、 執行緒退出和進程退出。這允許您將標準調試輸出消息與其余的調試器的歷史資訊關聯起來。

IntelliTrace 事件跟蹤:由 IntelliTrace 收集的每個其他事件類別將出現在這個時間表軌上:ADO.NET、ASP.NET、 主控台、 資料繫結、 環境變數,檔,手勢,延遲初始化,書記官處服務模型中,執行緒,跟蹤、 使用者提示和 XML。

診斷工具工具列:工具列使您可以放大和縮小按鈕,如重置視圖按鈕重置回預設縮放級別的時間軸,並清除任何現有的時間選擇。入眼簾,這個篩檢程式收集的所有資料。選擇工具下拉清單允許您選擇您想要包括在診斷工具視窗中,除了 IntelliTrace 的工具。

您可以在同一時間運行多個診斷工具。診斷工具視窗可以駐留記憶體,CPU 使用率工具和 IntelliTrace 都在同一時間。這使您到您的應用程式行為的整體視圖。例如, 圖 3 顯示了如何的一系列模組載入事件增加記憶體和 CPU 使用率為ASP.NET應用程式啟動時它。

診斷工具視窗顯示了您的應用程式是如何表現和表演
圖 3 診斷工具視窗顯示了您的應用程式是如何表現和表演

修復 IntelliTrace 與一個真正的 Bug

現在我將帶你通過使用 IntelliTraceVisual Studio2015年企業活調試功能的真正 bug 的修復。要調試的應用程式是從被稱為 SocialClub 的套接一個 Windows 表單應用程式。

應用程式維護一個資料庫的一個社交俱樂部的成員。該 bug 是該搜索行為不規律後註冊成會員。要重現該 bug,我啟動應用程式並註冊一個新成員。然後執行該函數將返回所有註冊的會員的得到所有搜索。我期望結果只有一個,但不是想要兩個 (見圖 4)。第二個搜尋結果是意外,所以這就是我需要修復。

得到所有搜尋結果都包含一個意外的記錄
圖 4 得到所有搜尋結果都包含一個意外的記錄

若要修復此錯誤,我應該怎麼接下來?在這一點上,我的假設是有毛病要麼得到所有的搜索功能或新成員註冊過程有毛病。應用程式有需要的特定搜尋條件,所以我會用它來搜索所得到所有 (一個丟失的資料與未知的值) 返回的意外記錄的另一種搜索模式。

以下幾種可能情況:如果沒有人得到,它可能意味著意外的記錄在資料庫中不存在和得到所有的搜索功能是的問題。如果我得到一個匹配記錄的未知的佔領和使用單身的結果,這一問題可能是與輸入資料庫中的記錄比它應該更多的註冊功能。

所以現在我執行搜索與未知的佔領和使用單身,未知的返回恰好只有一個結果:我成功註冊工程師以及結婚記錄。奇怪的是,不幸的是,它沒有我再靠近該 bug 的根源。而不是花時間設置中斷點、 新會員的註冊和搜索它們一遍又一遍,我會看到如何 IntelliTrace 可以説明加快調查。

我想要查看的事件收集 IntelliTrace,但 IntelliTrace 事件不會更新,直到調試器中斷應用程式的執行 (意思它遇到中斷點)。因為我沒有具體的中斷點,我感興趣,我只需按一下全部中斷Visual Studio工具列上。與所有線程暫停該應用程式現在是處於中斷狀態。IntelliTrace 時間軸和診斷工具視窗的表格式詳細資訊視圖中顯示它所收集的資料。

在這一點上,我已經會有點開始調試這與應用程式進行交互。我登錄、 註冊一個新成員,使用得到所有搜索,搜索與特定搜尋條件。然而,只是感興趣作為按一下註冊紀錄冊的直接結果發生的事件。若要篩選我只是這些事件的看法,我懸停在時間軸中的事件直到我找到我按一下註冊紀錄冊的位置。然後拖動並選擇一個群集事件。當我看著我表格的詳細視圖後選定後的時間,, 我可以看到兩個最近的事件所列 (比命中全部中斷其他) 是兩個 INSERT 語句 (請參見圖 5)。

表格詳細資訊視圖進行篩選以顯示來自所選時間範圍內的事件
圖 5 表格詳細資訊視圖進行篩選以顯示來自所選時間範圍內的事件

按一下清單中的事件可將其擴展到多行顯示整個執行的 SQL 語句。我可以有兩個 INSERT 語句發生的事情。第二個插入含有 Null 值的不良記錄。這裡有兩個 SQL 語句:

Execute Reader "insert [dbo].[ClubMembers]([Name], [DateOfBirth],
  [Occupation], [Salary], [MaritalStatus], [HealthStatus], [NumberOfChildren],
  [ExpirationDate])values (@0, @1, @2, @3, @4, @5, @6, @7)
  select [Id] from [dbo].[ClubMembers] where @@ROWCOUNT > 0 and [Id] =
  scope_identity()"
Execute Reader "insert [dbo].[ClubMembers]([Name], [DateOfBirth],
  [Occupation], [Salary], [MaritalStatus], [HealthStatus], [NumberOfChildren],
  [ExpirationDate])values (null, @0, @1, null, @2, @3, null, @4) select [Id] from
  [dbo].[ClubMembers] where @@ROWCOUNT > 0 and [Id] = scope_identity()"

您可以忽略後面插入的 SELECT 語句。這是記錄的Entity Framework檢索它剛才插入的 ID。接下來的問題是:為什麼我能註冊按鈕一次按一下執行兩個 SQL 語句?IntelliTrace 説明我迅速回答這個問題,讓我為每個事件啟動歷史調試 (見圖 6) 和檢查在呼叫堆疊視窗及其各自歷史呼叫堆疊。

啟動歷史調試兩個 INSERT 語句的第一個
圖 6 啟動歷史調試兩個 INSERT 語句的第一個

第一次插入歷史的呼叫堆疊是:

John.SocialClub.Data.dll!John.SocialClub.Data.Service.ClubMemberService.Create(...)
John.SocialClub.Desktop.exe!John.SocialClub.Desktop.Forms.Membership.Manage.RegisterMember()
John.SocialClub.Desktop.exe!John.SocialClub.Desktop.Forms.Membership.Manage.Register_Click(...)
John.SocialClub.Desktop.exe!John.SocialClub.Desktop.Program.Main()

第二個歷史呼叫堆疊與不良記錄插入是:

John.SocialClub.Data.dll!John.SocialClub.Data.Service.ClubMemberService.Create(...)
John.SocialClub.Desktop.exe!John.SocialClub.Desktop.Forms.Membership.Manage.RegisterMember()
John.SocialClub.Desktop.exe!John.SocialClub.Desktop.Forms.Membership.Manage.btnRegister_MouseClick(...)
John.SocialClub.Desktop.exe!John.SocialClub.Desktop.Program.Main()

點擊每個幀帶我到相應的程式碼。在檢查後的兩個歷史呼叫堆疊,我已經確定我有兩個不同的事件處理常式相同的按鈕按一下訂閱:Register_Click(...) 和 btnRegister_MouseClick(...)。閱讀那些兩個函數中的代碼,很快使人推斷出因為每個新的會員註冊後重置表單的欄位,第一個事件處理常式將記錄插入到資料庫正確。然而,第二個事件處理常式插入帶有空白和 NULL 欄位的記錄。所以我很快就發現 bug 使用全部中斷,然後用於 IntelliTrace 標識和導航到違規的程式碼片段。

如果 IntelliTrace 事件並不足以發現 Bug 嗎?

在這一點上,興奮你正如關於 IntelliTrace 改善你調試的方式,您可能想知道該怎麼辦如果 IntelliTrace 並不記錄任何有趣的事件,可能會導致 bug 的根源。你運氣不好嗎?不,你不是。Don忘了你可以控制哪些 IntelliTrace 事件啟用使用工具 |選項 |IntelliTrace |IntelliTrace 事件。並不是所有啟用預設情況下,但甚至使他們都可能不總是足以為一些令人討厭的 bug。

對於那些棘手的問題,您可以配置 IntelliTrace 記錄不只是事件,但也是每個方法調用和它的參數。只需轉到工具 |選項 |IntelliTrace 與選擇的 IntelliTrace 事件和調用資訊。這是一個功能強大的調試功能,但它在運行時成本來。使用此設置,IntelliTrace 將攔截每個方法調用,並記錄,它將會影響應用程式的性能。這就是為什麼它預設情況下,不會收集方法調用。你必須通過 IntelliTrace 設置中選擇。

您可以查看和導航中兩種不同方式的這一新資訊。您可以使用子選項卡電話在調試器事件詳細資訊表中,列出了所有記錄的電話 (在調用視圖上的詳細資訊,請轉到 aka.ms/itracecalls)。另一種方式是為事件啟動歷史調試和使用 IntelliTrace 控制項內的文字編輯器來來回回在應用程式的執行中導航。您的代碼和指令指標之間顯示的控制項。所以 IntelliTrace 有你覆蓋你活的調試方案。

如果你不能重現該 Bug 在開發機器上的嗎?

這是非生活的調試器調試進來的地方。 到目前為止,我假定你知道重現此問題,您正在調試的必要步驟。這並非總是如此。一些最困難、 最耗時的 bug 是那些,你可能沒有再現的準確步驟。IntelliTrace 可以消除這可怕的"無法再現"場景,讓你記錄在生產或測試環境上的應用程式的執行。然後您可以調試在開發電腦上通過探索使用同一個診斷工具視窗已經沿用在這裡收集到的資訊。

IntelliTrace 提供獨立收集器,您可以部署到Visual Studio不能連接到的其他環境。因為沒有安裝,您應該從您的管理員遇到任何抵抗。只是將收集器複製到目標環境。收集器記錄到一個.itrace 檔,您可以轉移到你的開發機器和用Visual Studio打開的應用程式的執行。這種情況下是作為非生活調試提到,因為您無法控制在調試時的應用程式執行。有關如何使用 IntelliTrace 獨立收集的最新資訊,請訪問 aka.ms/itracecollector

接近尾聲了

新的 IntelliTrace 經驗和與診斷工具視窗集成有一些令人興奮的可能性。你可以通過去保持最新的關於這些主題和其他診斷相關的功能的最新資訊 aka.ms/DiagnosticsBlog


Angelos Petropoulos 是Visual Studio團隊高級專案經理。在物件導向的軟體工程碩士後,他擔任聯合王國 IT 顧問。後搬到美國後,他加入的診斷工具團隊在Visual Studio,他現 IntelliTrace 的專案經理。

感謝以下的微軟技術專家對本文的審閱:安德魯 · 霍爾,Daniel 蛾Dan Taylor,Charles威利斯