使用Windbg调试StackOverflowException异常
最近公司服務器端程序遇到一個堆棧溢出問題,偏偏是偶發性但是又在相對固定時間發生的,有一個服務器比較容易觸發,平均隔個5、6天就會發生一次,且每次都是在8點23分左右拋出異常。服務器開發同事初步定位是定時器出了問題,單純看代碼看不出問題,打的log也沒看到有用的信息(其實這里是有點能力問題的,囧~看代碼也看得不認真不細致。打的log沒打到點上)。老大就把這個問題拋給我,讓我去解決一下,提示用一些工具直接去測,比如Windbg,于是開始了Windbg之旅。
上網搜索了下Windbg相關的博客,主要從以下兩篇文章中受益頗多。
文1 .NET應用程序調試—原理、工具、方法
文2 WinDbg-如何抓取dump文件
Windbg工具下載地址:http://www.microsoft.com/whdc/devtools/debugging/default.aspx
看完文章后決定使用分析dmp文件的方式來解決這次的問題。
首先是獲取dump文件。雖然用Windows系統自帶的任務管理器可以方便地dump文件,但是由于64位系統和32位進程(發生問題的后臺程序)的問題,這種方式獲得的dmp文件用Windbg分析不出東西,老是會報一些錯,所以采用其他方式,比較靠譜的有兩種,從上面文章中分別有提到。
一是文1提到的使用Windows調試工具箱中的ntsd工具,步驟為:1、cmd運行命令“Windows調試工具箱安裝目錄\x86\tlist”查看所有進程的PID,找到crash進程的id。2、cmd運行命令“Windows調試工具箱安裝目錄\x86\ntsd -pv -p 進程PID”。3、ntsd界面中運行命令“.dump/mf dmp文件路徑”即生成dmp文件。
二是文2提到的直接使用Windbg來dump文件,打開“Windows調試工具箱安裝目錄\x86\windbg.exe”,點擊File->Attach to a Process->選擇crash的進程->點擊確定,進到抓取dump的界面,在命令行中輸入“.dump -ma dmp文件路徑”生成dmp文件。
注意,這里的操作步驟都需要到發生crash的機器上且要在發生crash后沒關閉進程之前去執行;另外這里使用的是x86下的工具箱,具體的選擇可參照這篇文章 Windbg 32位版本和64位版本的選擇 。
拿到dmp文件后就可以用x86版本的Windbg工具打開了。這里簡要寫幾個調試時用到的命令。使用方法文1文2都有提到。
.sympath 路徑
.symfix+ 路徑
.reload
.loadby sos clr
!analyze -v
!threads
~0s
!clrstack
這里設置符號路徑時最好是程序所在目錄,且帶有pdb文件。使用!threads獲取所有線程的時候,哪個線程發生了Exception會顯示出來,使用~0s命令進入線程,使用!clrstack可以看到調用堆棧,從而可以看到問題所在了。
大致是這樣子,我看到了出現問題的代碼,原來有個定時事件發生在每天的5.50分,在觸發時因為代碼問題,會有小概率沒把這個下次時間(即明天5.50分)正確設置,導致今天的事件一直處于觸發中,而每次定時器輪詢是3秒間隔,到8.23分的時候剛好堆棧溢出。
至此,問題解決。第一次寫博客,不怎么會編輯,將就著看先。因為時間不夠,內容也不詳細,之后慢慢補充完整。
轉載于:https://www.cnblogs.com/qiups/p/5654544.html
總結
以上是生活随笔為你收集整理的使用Windbg调试StackOverflowException异常的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分治最小割 学习总结
- 下一篇: Redis 和 Memcached 的区