天天看點

Visual Studio調試器指南---多線程應用程式調試(二)

使用“并行堆棧”視窗:“線程”視圖

在“調試”菜單上,單擊“啟動調試”。 等待命中第一個斷點。

檢視一個線程的調用堆棧

  1. 在“調試”菜單上指向“視窗”,然後單擊“線程”。 将“線程”視窗停靠在 Visual Studio 底部。
  2. 在“調試”菜單上指向“視窗”,然後單擊“調用堆棧”。 将“調用堆棧”視窗停靠在 Visual Studio 底部。
  3. 在“線程”視窗中輕按兩下線程,使其作為目前線程。 目前線程具有一個黃色箭頭。 更改目前線程時,其調用堆棧顯示在“調用堆棧”視窗中。

檢視“并行堆棧”視窗

  1. 在“調試”菜單上指向“視窗”,然後單擊“并行堆棧”。 確定在左上角的框中選擇了“線程”。

    通過使用 "并行堆棧" 視窗,您可以在一個視圖中同時檢視多個調用堆棧。 下圖顯示了 "調用堆棧" 視窗上方的 "并行堆棧" 視窗。

    Visual Studio調試器指南---多線程應用程式調試(二)
    主線程的調用堆棧顯示在一個框中,其他四個線程的調用堆棧則劃分到另一個框中。 将這四個線程劃分在一起是因為其堆棧幀共享相同的方法上下文;也就是說,它們處于相同的方法中:

    A

    B

    C

    。 若要檢視共享同一框的線程的 Id 和名稱,請将滑鼠懸停在帶有标題的框上(4 個線程)。 目前線程以粗體顯示。
    Visual Studio調試器指南---多線程應用程式調試(二)

    黃色箭頭訓示目前線程的活動堆棧幀。

    通過右鍵單擊“調用堆棧”視窗,可以設定要顯示堆棧幀的多少詳細資訊(“子產品名稱”、“參數類型”、“參數名稱”、“參數值”、“行号”和“位元組偏移量”)。

    方框周圍的藍色突出顯示訓示目前線程是該框的一部分。 工具提示中的粗體堆棧幀也可訓示目前線程。 如果輕按兩下“線程”視窗中的主線程,可以看到“并行堆棧”視窗中的藍色突出顯示内容相應移動。

    Visual Studio調試器指南---多線程應用程式調試(二)

繼續執行到第二個斷點

  1. 若要繼續執行到命中第二個斷點,請在“調試”菜單上單擊“繼續”。 下圖所示為第二個斷點處的線程樹。
    Visual Studio調試器指南---多線程應用程式調試(二)

    在第一個斷點處,所有四個線程均從 S.A 執行到 S.B 再到 S.C 方法。 該資訊仍會顯示在“并行堆棧”視窗中,但是這四個線程已進一步執行。 其中一個線程繼續執行到 S.D 再到 S.E。 另一個線程繼續執行到 S.F、S.G 和 S.H。 其餘兩個線程繼續執行到 S.I 和 S.J,其中一個線程從此方法執行到 S.K,而另一個線程繼續執行到非使用者外部代碼。

    可以将滑鼠指針懸停在框标題(例如,“1 個線程”或“2 個線程”)上,以檢視線程的線程 ID。 将滑鼠指針懸停在堆棧幀上可以檢視線程 ID 和其他幀詳細資訊。 藍色突出顯示訓示目前線程,黃色箭頭訓示目前線程的活動堆棧幀。

    軟線程圖示(interweaved lines)訓示非目前線程的活動堆棧幀。 在“調用堆棧”視窗中,輕按兩下 S.B 可以切換幀。 “并行堆棧”視窗通過使用綠色的曲線箭頭圖示訓示目前線程的目前堆棧幀。

    在“線程”視窗中進行線程切換時,“并行堆棧”視窗中的視圖相應更新。

    可通過在“并行堆棧”視窗中使用快捷菜單來切換到其他線程或其他線程的其他幀。 例如,右鍵單擊 S.J,指向“切換到幀”,然後單擊某一指令。

    Visual Studio調試器指南---多線程應用程式調試(二)
    右鍵單擊 S.C,指向“切換到幀”。 其中一個帶有選中标記的指令訓示目前線程的堆棧幀。 您可以切換到相同線程的上述幀(将僅移動綠色箭頭),也可以切換到其他線程(将同時移動藍色突出顯示)。 下圖所示為子菜單。
    Visual Studio調試器指南---多線程應用程式調試(二)

    當方法上下文隻與一個堆棧幀關聯時,框标題顯示“1 個線程”,輕按兩下它即可切換到該線程。 如果輕按兩下關聯有一個以上的幀的方法上下文,則會自動彈出該菜單。 将滑鼠指針懸停在方法上下文上時,請注意右側的黑色三角形。 單擊該三角形也可以顯示該快捷菜單。

    對于具有多個線程的大型應用程式,您可能隻希望關注某個線程子集。 “并行堆棧”視窗可僅顯示已标記線程的調用堆棧。 若要标記線程,請使用快捷菜單或線程的第一個單元格。

    在工具欄上,單擊清單框旁邊的“僅顯示已标記項”按鈕。

    Visual Studio調試器指南---多線程應用程式調試(二)
    現在,隻有已标記的線程才會顯示在 "并行堆棧" 視窗中。

繼續執行到第三個斷點

  1. 若要繼續執行到命中第三個斷點,請在“調試”菜單上單擊“繼續”。

    如果有多個線程位于同一方法中,但該方法不在調用堆棧開頭,則會在不同框中顯示該方法。 目前斷點處的一個示例是 S.L,它包含三個線程并在三個框中顯示這三個線程。 輕按兩下 S.L。

    Visual Studio調試器指南---多線程應用程式調試(二)
    請注意,S.L 在其他兩個框中為粗體,這樣您可以看到 S.L 的其他顯示位置。 如果希望檢視對 S.L 進行調用的幀和 S.L 所調用的幀,請單擊工具欄上的“切換方法視圖”按鈕。 下圖顯示了 "并行堆棧" 視窗的 "方法" 視圖。
    Visual Studio調試器指南---多線程應用程式調試(二)

    請注意以上關系圖以所選方法為中心并将其單獨放在視圖中間的方框中。 被調用方和調用方分别顯示在頂部和底部。 再次單擊“切換方法視圖”按鈕可以退出該模式。

    “并行堆棧”視窗的快捷菜單還包括以下其他項。

    • “十六進制顯示”,用于在十進制和十六進制之間切換工具提示中的數字。
    • 符号設定打開各自的對話框。
    • 在源中顯示線程在源代碼中切換線程标記的顯示,這些線程标記顯示源代碼中的線程位置。
    • “顯示外部代碼”,用于顯示所有幀(即使這些幀未處于使用者代碼中)。 使用此項可檢視展開的關系圖,其中包含其他幀(這些幀可能因沒有相應符号而灰顯)。
  2. 在“并行堆棧”視窗中,確定已啟用工具欄上的“自動滾動到目前堆棧幀”按鈕。

    如果關系圖較大,當單步執行到下一斷點時,您可能希望視圖自動滾動到目前線程的活動堆棧幀;即第一個命中該斷點的線程。

  3. 繼續之前,請在“并行堆棧”視窗中一直滾動到左側和底部。

繼續執行到第四個斷點

  1. 若要繼續執行到命中第四個斷點,請在“調試”菜單上單擊“繼續”。

    請注意視圖如何自動滾動到位。 在“線程”視窗中切換線程或在“調用堆棧”視窗中切換堆棧幀,并注意視圖如何一直自動滾動到正确的幀。 禁用“自動滾動到目前工具幀”選項并檢視不同之處。

    “鳥瞰圖”還有助于在“并行堆棧”視窗中處理大型關系圖。 預設情況下,鳥瞰圖為 on。 但是,您可以通過單擊視窗右下角滾動條之間的按鈕來對其進行切換,如下圖所示。

    Visual Studio調試器指南---多線程應用程式調試(二)

    在鳥瞰視圖中,你可以移動矩形以便在關系圖中快速平移。

    朝任意方向移動此關系圖的另一種方法是:單擊此關系圖的空白區域并将其拖動到所需位置。

    若要放大和縮小此關系圖,請按住 Ctrl 并移動滑鼠滾輪。 或者,也可以單擊工具欄上的“縮放”按鈕并使用縮放工具。

    通過單擊“工具”菜單和“選項”,并選中或清除“調試”節點下的相應選項,還可以按從上到下(而不是從下到上)的方向檢視堆棧。

  2. 繼續之前,請在“調試”菜單上單擊“停止調試”以結束執行。

使用“并行任務”視窗和“并行堆棧”視窗的任務視圖

繼續之前,建議您先完成前面的過程。

重新啟動應用程式,直到命中第一個斷點

  1. 在“調試”菜單上,單擊“啟動調試”并等待命中第一個斷點。
  2. 在“線程”視窗中輕按兩下線程,以将其作為目前線程。 目前線程具有一個黃色箭頭。 更改目前線程時,将更新其他視窗。 接着,我們将檢視任務。
  3. 在 "調試" 菜單上,指向 "視窗",再單擊 "任務"。 下圖顯示了 "任務" 視窗。
    Visual Studio調試器指南---多線程應用程式調試(二)

    對于運作的每一項任務,您可以讀取其 ID(由名稱相同的屬性傳回)、運作該任務的線程的 ID 和名稱以及任務位置(懸停以顯示具有整個調用堆棧的工具提示)。 此外,“任務”列下還會顯示傳遞到任務中的方法,即起始點。

    可以對任何列進行排序。 請注意訓示排序列和方向的排序标志符号。 您還可以通過向左或向右拖動列來對列重新排序。

    黃色箭頭訓示目前任務。 通過輕按兩下某一任務或使用快捷菜單可以切換任務。 切換任務時,基礎線程即成為目前線程并更新其他視窗。

    在不同任務之間進行手動切換時,黃色箭頭将相應移動,而白色箭頭仍顯示導緻調試器中斷的任務。

  1. 若要繼續執行到命中第二個斷點,請在“調試”菜單上單擊“繼續”。

    之前,"狀态" 列将所有任務顯示為 "活動",但現在兩個任務被阻止。 任務可能因多種不同原因而被阻止。 在“狀态”列中,将滑鼠指針懸停在正在等待的任務上可以檢視其阻止原因。 例如,在下圖中,任務 3 正在等待任務 4。

    Visual Studio調試器指南---多線程應用程式調試(二)
    任務 4 又在等待配置設定給任務 2 的線程所擁有的螢幕。 (右鍵單擊标題行,然後選擇 "列" > 線程配置設定檢視任務2的線程配置設定值 ")。
    Visual Studio調試器指南---多線程應用程式調試(二)

    可以通過單擊 "任務" 視窗第一列中的标志來标記任務。

    使用标記功能可以跟蹤同一調試會話中的不同斷點之間的任務或篩選“并行堆棧”視窗中顯示的調用堆棧所對應的任務。

    在先前使用“并行堆棧”視窗時,已檢視了應用程式線程。 請再次檢視“并行堆棧”視窗,但這次檢視應用程式任務。 請在左上方的框中選擇“任務”來執行此操作。 下圖所示為任務視圖。

    Visual Studio調試器指南---多線程應用程式調試(二)

    目前未在執行任務的線程不會顯示在“并行堆棧”視窗的任務視圖中。 此外,對于執行任務的線程,某些與任務無關的堆棧幀将從堆棧的頂部和底部篩選掉。

    再次檢視 "任務" 視窗。 右擊任何列标題可以檢視該列的快捷菜單。

    您可以使用此快捷菜單添加或移除列。 例如,AppDomain 列未處于選中狀态;是以,不會在清單中顯示它。 單擊“父級”。 此時将顯示“父級”列,但不顯示四個任務中任何任務的值。

  1. 此時,新任務(即任務 5)正在運作,而任務 4 則處于等待狀态。 通過将滑鼠指針懸停在“狀态”視窗中正在等待的任務上,可以檢視其原因。 請注意,父列中的任務4是任務5的父項。

    若要更好地直覺顯示父子關系,請右鍵單擊列标題行,然後單擊 "父子視圖"。 您應看到以下圖示。

    Visual Studio調試器指南---多線程應用程式調試(二)
    請注意,任務4和任務5正在同一線程上運作(如果它是隐藏的,則顯示 "線程配置設定" 列)。 此資訊不會顯示在 "線程" 視窗中;這裡看到的是 "任務" 視窗的另一個優點。 為确認這一點,請檢視“并行堆棧”視窗。 確定你正在檢視“任務”。 在任務視窗中輕按兩下任務4和5。 執行此操作時,“并行堆棧”視窗中的藍色突出顯示内容随之更新。 此外,還可以通過掃描“并行堆棧”視窗上的工具提示來查找任務 4 和任務 5。
    Visual Studio調試器指南---多線程應用程式調試(二)
    在“并行堆棧”視窗中右鍵單擊 S.P,然後單擊“轉到線程”。 此時,視窗将切換到線程視圖,并顯示相應幀。 你可以在同一線程上檢視兩個任務。
    Visual Studio調試器指南---多線程應用程式調試(二)
    這是“并行堆棧”視窗中的任務視圖相較于“線程”視窗的另一優勢。

若要繼續執行到命中第三個斷點,請在“調試”菜單上單擊“繼續”。 單擊要按 ID 排序的“ID”列标題。 您應看到以下圖示。

Visual Studio調試器指南---多線程應用程式調試(二)

由于任務 5 已完成,是以不再顯示該任務。 如果計算機上并非如此并且未顯示死鎖,請通過按“F11”單步執行一次。

任務3和任務4現在正在等待,并被阻止。 此外,還存在 5 個作為任務 2 的子級的新任務,目前已計劃這些任務。 已計劃任務是已在代碼中啟動但尚未運作的任務。 是以,其“位置”和“線程配置設定”列為空。

再次檢視“并行堆棧”視窗。 每個框的标題都具有一個顯示線程 ID 和名稱的工具提示。 在“并行堆棧”視窗中切換到任務視圖。 将滑鼠指針懸停在标題上可以檢視任務 ID 和名稱以及任務狀态,如下圖所示。

Visual Studio調試器指南---多線程應用程式調試(二)

可以按列對任務進行分組。 在 "任務" 視窗中,右鍵單擊 "狀态" 列标題,然後單擊 "按狀态分組"。 下圖顯示按狀态分組的 "任務" 視窗。

Visual Studio調試器指南---多線程應用程式調試(二)

此外,還可以按其他列進行分組。 通過對任務進行分組,你可以關注某個任務子集。 每個可折疊的組都包含一個分組在一起的項的計數。