如何運用 debugger 了解程式錯誤的位置

在這一次實習(3bags4.rar)裡, 很多同學遇見下圖這樣的錯誤, 第一個反應就是 --- 又掛了, 系統好爛, 程式好難寫, 然後按下 "不回報", 默默地, 盲目地開始找錯誤... 邊找心裡面邊罵 *)&*)&(*

其實像這樣的錯誤常常會發生, 程式越寫越大的時候, 如果你盲目地去找錯誤, 那就像是大海撈針一樣, 常常會徒勞無功。

我們寫一個程式的時候常常需要用到系統提供的一些函式, 例如 new, delete 這些記憶體的處理函式, 或是 vector, string 這類的工具, 或是 cin >> , cout <<, getline 等等 io 的工具,當這些函式裡出現錯誤時, 常常錯誤就會發生在一個你不認得的系統檔案裡; 另外你在處理指標時有記憶體存取的錯誤, 也常常會跳出這個畫面...

那麼我們怎麼在最短的時間裡找到究竟是我們程式裡哪一列的使用造成這樣的錯誤呢?

關鍵就在運用 source debugger (平常寫程式的時候不能一遇見錯誤就立刻用 source debugger 一列一列的看程式如何執行, 那是初學者才會做的事; 但是這個時候卻最好是用 debugger 來確定到底是哪裡發生錯誤), 在下圖中按下 "除錯" 來開啟 source debugger

請注意: 如果你的程式有呼叫 system("pause"); 的話, VC2010/VC2008/VC6 中請 按下任意鍵繼續 之後才看得到這個畫面

然後會看到如下的選擇偵錯工具畫面:

然後會看到如下的存取違規錯誤畫面:

按下中斷後你會看到下列偵錯畫面

此時可以看到上圖中 呼叫堆疊窗格 裡出現系統呼叫堆疊的內容, 代表目前執行到 3bags4.exe!main() 函式, 在 main.cpp 第 34 列處呼叫 3bags4.exe!Game::~Game() 解構元函式, 然後在 Game.cpp 的第 17 列處 Game::~Game() 函式呼叫 bag.cpp 的第 17 列處3bags4.exe!Bag::~Bag() 解構元函式, 並且執行到 ball.cpp 的第 10 列 3bags4.exe!Ball::isRed() 函式內發生上述存取違規錯誤, 不過 isRed() 函式內看不出來有什麼錯, 也許發生在呼叫這個函式的地方

在上圖中 3bags4.exe!Bag::~Bag() 那一列上點兩下就可以看到 Bag.cpp 中的第 17 列, 也就是 m_balls[0]->isRed(); 這個敘述, debugger 很快地告訴你, 你的程式執行到這裡發生錯誤了, 你可以專心地分析一下自己程式的邏輯, 看看為什麼會錯, 不需要盲目地去找錯誤或是向別人求助。

按下 偵錯/停止偵錯, 不回報 來結束 source debugger

如果你在介面裡看不到呼叫堆疊的話, 可以參考下圖, 在工具列上點選下拉選單, 選擇 呼叫堆疊 (或是 Alt+7)

再不然, 如下圖, 你也可以在工具列上找到 堆疊框架

這個是你一定要會用的東西, 不要每次程式發生記憶體存取錯誤時, 連在哪裡出錯都弄不清楚

C++ 物件導向程式設計課程 首頁

製作日期: 03/13/2013 by 丁培毅 (Pei-yih Ting)
E-mail: pyting@mail.ntou.edu.tw TEL: 02 24622192x6615
海洋大學 電機資訊學院 資訊工程學系 Lagoon