WINCE下如何診斷應用程式崩潰

2021-06-07 22:40:56 字數 2799 閱讀 7002

無論你是乙個單純的電腦使用者還是一名高階軟體工程師,都一定對程式崩潰不陌生。做為一名windows ce應用程式開發者,你也一定遇到過下圖這種場景:

這個對話方塊告訴你,有乙個叫installer.exe的程式在位址00019320處崩潰了。如果這個程式歸你負責,那麼你的問題就來了:怎麼找出這個bug?這篇文章我想談談我在這方面的一些經驗。

windows ce的崩潰介面給出的資訊十分的少,其中最有用的無疑是崩潰位址,如果你能從崩潰位址定位到源**去,這個問題可以說就解決了一半。

從位址定位到源**的方法有幾種。一種是利用map檔案:你可以在build程式時生成map檔案。map檔案是乙個文字檔案,其中主要記錄了各個函式入口對應的位址資訊。比如這個例子中,崩潰位址對應的入口是:

0001:000082f4 ??1?$ccomptr@uiimage@@@atl@@qaa@xz

000192f4 f i imageviewer.obj

map檔案的好處是它是文字檔案,可以人工閱讀,缺點是資訊不夠多,只能定位到函式級別,而且要看懂map檔案你需要有足夠的經驗,比如其中那串長長的貌似亂碼的字串是c++函式經過name mangling處理後的結果,沒有一定的經驗你根本沒法還原出實際的函式。

另一種方法是利用pdb檔案,pdb檔案收集了應用程式的除錯符號。pdb檔案提供的資訊很全,不過你得需要一定的工具才能解讀它。如果你是乙個經驗豐富的windows桌面平台的應用程式開發者,你可能聽說過msj(microsoft system journal)這本雜誌。如果你曾經看過這本雜誌,應該對bugslayer不陌生。在這篇文章中,bugslayer介紹了他做的乙個工具:crashfinder。crashfinder可以從崩潰位址通過查詢相應的pdb檔案直接定位到導致崩潰的源**行。幸運的是,由於windows ce可執行程式及其pdb檔案的格式和windows桌面系統上的是一樣的,因此crashfinder也可以用來定位windows ce程式的崩潰位址。下面是crashfinder顯示的結果:

crashfinder提供的資訊十分有用,但是不夠直觀。為此我在remote process explorer提供了乙個更方便的介面,它可以直接顯示源**,並把導致崩潰的那一行highlight出來:

pdb檔案裡包含著大量的除錯資訊可以幫助你診斷應用程式錯誤,因此一般來說即使是正式release的版本,你也應該生成並維護好這些pdb檔案。使用pdb檔案的關鍵是崩潰的應用程式和pdb檔案一定要匹配,否則它不但不能幫到你,反而會誤導你。下圖是vs2005中設定生成pdb檔案和map檔案的地方:

前面說過,windows ce的崩潰介面給出的資訊十分少,很多時候我們還需要更多的資訊才能定位問題,另外有些windows ce裝置可能根本沒有顯示器。為解決這一問題,windows ce在應用程式崩潰時還同時往外(一般是串列埠)輸出相關的崩潰資訊。比如這個例子中,如果你正好接著除錯串列埠,開著hyperterminal,那麼在程式崩潰的時候你會看到這樣的資訊:

data abort: thread=8d661000 proc=81a477c0 'installer.exe' 

aky=00000401 pc=00019320(installer.exe+0x00009320) ra=00019094(installer.exe+0x0 

0009094) bva=16080100 fsr=00000007

我相信windows ce開發者一定也對這幾行資訊很熟悉。怎麼利用這些資訊診斷程式的問題?這裡面最關鍵的資訊是pc和ra給出的位址資訊。pc就是上面提到的崩潰位址,根據這個位址用crashfinder或者我的remote process explorer裡的crack address介面可以定位到導致崩潰的源**行;ra是pc的返回位址(return address),根據這個位址可以找到導致崩潰的上一級函式,這個資訊也很重要,因為很多時候崩潰的原因往往是上層函式往底層函式傳遞了非法引數導致的,比如你的應用程式用乙個非法的視窗類呼叫mfc函式,崩潰位址在mfc函式裡面,但是出問題的地方在你的呼叫**裡。下圖是ra位址對應的源**:

除了pc和ra,其他資訊也可以提供一些參考作用:bva是arm中的fault address register(far),是引起data abort的虛擬位址,比如說你的程式試圖訪問乙個非法位址裡的內容,那麼data abort時bva就是這個非法位址;fsr是fault status register,指明導致異常的原因,fsr的解釋可以看這裡。要注意的是thread和proc給出的不是thread id/thread handle或者process id/process handle,它們給出的是該thread或proc對應的核心物件的指標,類似於window nt平台的teb和peb的概念。由於你看到崩潰資訊時執行緒已經退出了,因此根據這個資訊在事後你無法知道是哪個執行緒出的錯。以後我將介紹一種系統級的logging機制,這種機制可以把每條log的thread id、teb等資訊同時記錄下來,這樣在崩潰時就可以根據data abort的teb資訊和先前log中出現的teb,找到出錯的執行緒。這樣,你不但可以定位到錯誤的源**,還能找到執行錯誤**的執行緒,將大大提高解決問題的效率。

如何診斷Windows CE的應用程式崩潰

無論你是乙個單純的電腦使用者還是一名高階軟體工程師,都一定對程式崩潰不陌生。做為一名windows ce應用程式開發者,你也一定遇到過下圖這種場景 這個對話方塊告訴你,有乙個叫installer.exe的程式在位址00019320處崩潰了。如果這個程式歸你負責,那麼你的問題就來了 怎麼找出這個bug...

WinCE應用程式的開發

wince應用程式的開發是wince開發中很重要的乙個環節。本文將簡單介紹一些wince應用程式開發的基本概念。先說開發工具,目前用得比較多的開發工具有evc4 sp4 vs2005 vs2008和platform builder。其中platform builder主要是用來定製作業系統的,雖然也...

wince應用程式如何呼叫控制面板的程式

我們在做一些專案時,有時會要求輸入一些引數來對系統進行設定,本來這些引數在控制面板中可以設定,但產品又不可能要求使用者自己開啟控制進行設定。如果可以在程式中呼叫控制面板中的引數設定對話方塊,就ok了,即省略了開發的步驟,又減少使用者操作的繁瑣,下面我講一下如何在程式中呼叫控制面板中的對話方塊。本人對...