[程式技巧] 腦殘 (簡易, 無痛) Windows NT (Win32) Service VC++ Debug (除錯) 方式
這次為了拜金勇者還有以後網路遊戲伺服器需要,需要寫一個 Windows NT Service (或者現在微軟改名叫做 Win32 Service)。
MSDN 裡面有個範例很不錯,執行起來也正常。
可惜的是,翻遍 MSDN 與網路搜尋,總是找不到滿意的 Debug (除錯) 方式。因為 Service 啟動與執行的過程中,不會開出任何視窗,甚至無法跳出任何 Dialog 顯示資訊 (用 MessageBox() 還會當機)。
所以,MSDN 提供的官方除錯方式,或是網路上討論的方法,不是太複雜需要弄東弄西,就是不知所云。還有看到很多人其實也為這所苦。要靠只是輸出除錯訊息,沒辦法設立中斷點,其實是很痛苦的事。
最後,從線上 MSDN 文件還有這個範例的 Source Code 裡面,發現有個方法,雖然很腦殘,但至少行得通。為避免自己忘記,也提供給正在苦惱的網友做個參考,所以趕快上來部落格公開分享。
- 首先,依照範例裡面的註解,想要除錯的時候,請把 StartService() 之前的 DebugBreak(); 該行取消註解(如果你拿到的範例沒有,請自行加上 DebugBreak() 的指令,MSDN 有指令詳細說明)。將 .exe 輸出改成 Debug (或 WinDebug) 模式,才可以包含所有 VC++ Debug 模式下的指令,並載入除錯符號表。
這時候,如果按 F5 開始執行,就會出現一個 Debug Dialog ,說是有中斷發生。若不想執行,直接按 F7 編譯成執行檔即可。
然後,按照正常程序,把 Service 用 CreateService() 註冊。在範例裡面,是下 "-i" 的執行參數。 - 再來,開啟 Service Control Panel ,這個也有 VC++ 範例,網路上也有許多人寫類似的程式,在此就不贅述,下面這個則是我自己用 VB 寫的。
如果剛剛 Service 有安裝好,正常的狀態應該是 Service Stopped。
然後,啟動你自己寫的 Service 。這裡要注意,從啟動 Service 的指令下達開始,緊接著的步驟,需要在 15 ~ 30 秒內完成,否則 Windows 就會認為 Service 發生錯誤沒辦法啟動,會停止它。 - 重點來了。程式會出現下面的畫面,一開始我還以為是程式當掉!結果不是,這個畫面會出現,原因就是剛剛在 VC++ Source code 裡面,下達 DebugBreak(); 命令造成的。
這時候請「火速」按下「除錯」按鈕。 - 終於,看到 VC++ (MSDEV.exe) 被載進來,並且跳出一個 Dialog 告訴你,發生了中斷。
先不管三七二十一,馬上再次「火速」按下 F5,趕在 15 ~ 30 秒內,讓你的 Service 程式繼續動起來。
如果你發現程式繼續在運作 (Title Bar 有 [run] 字樣出現),沒有跳出 Service 被 Windows 強停的錯誤訊息畫面跳出來,就表示成功了!Windows 已經認為 Service 成功啟動,不會再繼續監視你的 Service ,就可以不用繼續那麼急驚風,進入自己的除錯程序。 - 這邊要開始進入普通的除錯程序。先在選單 Debug 項目選擇 Break 指令,把程式中斷。
如果只看到一大堆 Assembly 的指令,也沒看到自己的程序在 Call Stack 視窗出現,不用緊張。再選擇選單的 Debug 項目,並按下 Threads 項目(在下面的圖片中是灰色 Disable 不能按,必須先用 Break 停下程式,才可以按它。)。 - 應該會出現類似下面的 Thread 選擇視窗,就可以點選正在執行你想看的程序的那條 Thread ,開始除錯這條 Thread (就跟一般 Multi-Thread 的除錯方式一樣)。
- 常用 VC++ 的人應該會知道,以非設立中斷點的方式,強制中斷以後,常常會進入 Disassembly Code 視窗。
沒有關係,多按幾次 F10 或 F11,直到出現 Disassembly 跟你的 C++ Source 同時出現的畫面,就可以了。 - 最後,就看個人習慣。如果你並不關心 Source Code 被編譯成怎樣的 Assembly code,只要關閉 Disassembly Code 的視窗,就會回到如下面的圖片所示的一般正常 C++ Source Code 畫面,進入跟平常一樣的除錯程序。
可以看下面的範例,除錯視窗內的訊息也可以看見了!
請記得,這個方法每次啟動,就會執行 MSDEV.exe ,而叫出一次 VC++ 的 IDE 介面。所以,除錯結束時,要記得關閉該次啟動的 VC++ ,否則就會一直跑出很多 VC++ 的執行畫面,搞不清楚哪一個才是正在除錯中的。
沒有留言:
張貼留言