一些比較少人知道的 VisualStudio 偵錯功能

這篇主要是針對微軟 VisualStudio Team 部落格的《7 lesser known hacks for debugging in Visual Studio》和《7 More Lesser-known Debugging Tactics for Visual Studio》這兩篇文章,做簡單的整理。

在 Heresy 來看,微軟的 Visual Studio 算是目前數一數二的程式開發環境。不過另一方面,它的功能也相當地多,多到一般人應該有超過七成的功能都沒有用過。而在這些從來沒用過、甚至從來不知道的功能裡面,其實有些是相當實用、相當方便的!

微軟在這邊就是列出了 7 + 7 個罕為人知的 debug 技巧,來分享給開發者;不過裡面有的內容是針對 C# 這類 managed code 的,有的則是針對原生 C++ 的,並非全部都可以使用。

而這邊 Heresy 則是稍微再重新整理一些 C++ 可以用、個人也覺得比較有用的出來了~

另外,這邊所列的功能,大多是在 Visual Studio 2015 就已經有的,不過還是有部分功能是 Visual Studio 2017 才有的;如果是 2017 才有的,這邊也會特別強調。


跳到特定的陳述式(Set Next Statement)

這個功能是在 Visual Studio 2015 就可以用的功能,而在 2017 版則是簡化了他的操作。

在 Visual Studio 中進行偵錯,中斷的時候,一般是可以使用 F10 來逐行執行程式,進行分析;另外也可以透過 Ctrl + F10(執行至游標處),直接執行到滑鼠游標所在的位置。

但是實際上,在偵錯模式是,Visual Studio 在原始碼的右鍵選單中,還有一個「設定下一個陳述式」(Set Next Statement)的功能(Ctrl + Shift + F10),可以直接讓 Visual Studio 無視原本的順序、跳到特定陳述式。

透過這樣的方法,就可以在不修改程式的情況下,透過偵錯模式,來調整程式的執行順序;例如可以跳過某些程式碼,或甚至直接跳回之前的段落。如果程式本身編譯要很久的話,這樣可以不用重新編譯的調整流程功能,某方面來說,也算滿實用的了。


Visual Studio 2017 中,則是進一步簡化這個功能的操作。

在 VS 2017 裡,在偵錯模式中斷的情況下,把滑鼠游標移到每一行程式碼的前面,都會有一個往右的綠色箭頭,代表本來的「執行至游標處」,只要點下去,他就會依序執行到這一行。

而如果在此時壓住鍵盤的 Ctrl 的話,綠色的箭頭就會變成黃色的,而此時點下去,他就是「設定下一個陳述式」的功能,可以讓 Visual Studio 把標記移到這邊,告訴他接下來要執行這邊的程式碼。

下面的動畫圖,就是官方提供的示意:


修改變數的值

Visual Studio 在偵錯時另一個有趣的功能,是許允開發者可以不修改程式碼、直接修改變數的值。

也就是說,如果偵錯進行到一半,發現某個變數計算錯誤了,此時可以選擇不要修改程式重新偵錯,而是直接把這個值修改成正確的值,然後繼續執行下去。

而要在偵錯時修改變數的值,有三種方法。

  1. 在「資料提示」(DataTips)的地方直接修改

    在偵錯模式時,把滑鼠游標移動到變數上,會出現一個小小的浮動視窗、顯示這個變數的名稱和值。而這時候,點選他的值的部分,就可以修改他的值,然後繼續偵錯了。

  2. 在變數視窗(自動變數、區域變數、監看式)(Autos, Locals, Watch windows)中修改

    當透過自動變數、區域變數或監看式的視窗來觀察變數的資料的時候,用滑鼠雙集值的位置,也可以修改變數的數值。

  3. 使用「即時運算視窗」(Immediate window)修改

    在「即時運算視窗」裡面,可以直接在這邊修改變數的值。

    這個視窗的開啟方法,是點選工具列的「偵錯」、「視窗」、「即時運算」。

    不過這部分 Heresy 以 C++ 專案測試總覺得怪怪的,像是要把整數 x 改成 10 的話,不能輸入「x=10;」而是得輸入「x=10」…


在「呼叫堆疊」顯示參數值(Show parameter values in the Call Stack)

Visual Studio 的「呼叫堆疊」(Call Stack)視窗可以很方便地看出來目前程式執行的地方,是從那些函式一路呼叫下來了,相當地方便。

而實際上,他還有一個預設被關閉的選項、「顯示參數值」(Show Parameter Values ),在開啟後是可以讓偵錯時更方便地了解函式呼叫的狀況的~

只要在「呼叫堆疊」的視窗按右鍵,就可以找到這個選項了。本來只會顯示有哪些參數,開啟之後就會直接把呼叫時所傳進來的參數值也顯示出來了。

這個視窗的開啟方法,是點選工具列的「偵錯」、「視窗」、「呼叫堆疊」。


使用「平行監看式」來確認遞迴函式中的值(Look at values throughout recursive function calls)

「平行監看式」(Parallel Watch)這個視窗基本上是設計用來針對多執行序程式,同時監控不同執行序中的資料用的工具。

不過,他實際上也可以用來監控遞迴函式每個階段的狀態~

只要在偵錯狀態下開啟「平行監看式」(點選工具列的「偵錯」、「視窗」、「平行監看式」),並在各個欄位輸入要監看的式子、或是變數,接下來在執行遞迴函式的時候,就可以看到這些監看式在每次遞迴時的值了!


中斷點的進階使用

一般在使用 Visual Studio 的中斷點的時候,大多是會再要停止的程式碼前面,逐行加入中斷點,讓 Visual Studio 執行到這行的時候就停下來。

不過實際上,Visual Studio 的中斷點,事還有很多進一步的功能可以使用的!包括了可以設定中斷點的條件,或是去監看某個記憶體位址、當值有變化的時候中斷。這些中斷點的進階功能,都可以更方便地根據變數來做中斷的控制。


附加中斷條件

其中一個方法,是在中斷點上附加條件,只有在值有變化、或是符合指定條件時,才中斷程式。

要使用這個方法,基本上就是先透過本來的方法,在程式碼中加入中斷點(可以用快速鍵 F9);然後在中斷點的紅圈上按下滑鼠右鍵、選擇「條件」(condition)。接下來就只要在跳出的框框中,輸入自己需要的條件就可以了。


監控記憶體位址

而另一個只能用在原生 C++ 的方法,則是直接去監控記憶體位址,當變數值改變時就停止。

這個方法可以透過點選工具列的「偵錯」、「新增中斷點」、「資料中斷點」,來教出對應的視窗。在裡面,只要輸入變數的記憶體位址(或是用「&myVal」的形式)、以及對應的位元組數,就可以了。

這樣設定後,不管是在任何地方修改到這個變數,Visual Studio 都會停下來。所以如果是某個變數在不知道哪裡被修改的時候,這樣的中斷方式是非常有用的!

不過這邊也要注意,由於每次執行的時候,記憶體位址都會變化,所以當程式結束後,這個中斷點就會被停用;如果要重新啟用,則需要手動再做設定。


針對函式名稱中斷

Visual Studio 另外還有提供一個「函式中斷點」(Function breakpoint)的功能,可以讓使用者直接輸入函式名稱來完成設定。

透過這個方法來設定中斷點的好處,主要是可以不用手動去找到要中斷的函式的實際位置,只要知道名稱、就可以中斷了!

而這個方法的使用條件也很簡單,只要點選工具列的「偵錯」、「新增中斷點」、「函式中斷點」,然後再輸入函式名稱就可以了。


使用中斷點視窗檢查、管理所有中斷點

點選工具列的「偵錯」、「視窗」、「中斷點」,可以打開「中斷點」的視窗;在這個視窗裡面,可以看到所有的中斷點,同時也可以進行中斷點的新增。

當之前加了一堆中斷點,想要大量修改的時候,這個視窗會是相當好用的工具。


這篇就先寫到這裡吧~本來兩篇文章裡面,還有一些針對多執行序程式偵錯的技巧,目前是沒什麼需求,等之後有碰到再說吧~ :p

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。