天天看點

抓蟲記之十:誤殺自己的指令

今天一位同僚找我看了一個非常有意思的BUG,在一個彈出的非模态窗體上面,按下【Ctrl + S】,彈出儲存檔案窗體,點選取消好,報出0x80808080位址通路錯誤。但是程式中沒有停下斷點。

先看這個位址很有意思吧?這麼有規律的,絕對很有來頭,不過這個BUG先不講這個。

這個BUG還是很容易跟蹤下來的。不過說是容易,也費了不少勁,因為消息循環有其特有的特征,在WndProc裡是不能随便下斷點的。那如何跟蹤呢?

有人想到ExceptionLog,加入異常機制。這反而麻煩了。其實就是慢慢跟蹤代碼,進行簡單分析。基本就能定位到了。

原來,在彈出的窗體中的消息進行中,響應完消息後,會調用自己定義的消息回調事件,如下:

inherited WnProc(Msg);

If Assigned(FOnMessage) then FOnMessage(Self, Msg);

第一行代碼,在基類中,會自動調用全局消息處理,關鍵是,這位同僚的系統中,在儲存的時候,釋放掉了一些窗體,包括目前彈出的窗體。

也就是說,第一行代碼執行完成之後,目前對象執行個體就已經被釋放了。是以第二句話,就會出現位址通路錯誤了。

繼續閱讀