标签:
最近公司服务器端程序遇到一个堆栈溢出问题,偏偏是偶发性但是又在相对固定时间发生的,有一个服务器比较容易触发,平均隔个5、6天就会发生一次,且每次都是在8点23分左右抛出异常。服务器开发同事初步定位是定时器出了问题,单纯看代码看不出问题,打的log也没看到有用的信息(其实这里是有点能力问题的,囧~看代码也看得不认真不细致。打的log没打到点上)。老大就把这个问题抛给我,让我去解决一下,提示用一些工具直接去测,比如Windbg,于是开始了Windbg之旅。
上网搜索了下Windbg相关的博客,主要从以下两篇文章中受益颇多。
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分的时候刚好堆栈溢出。
至此,问题解决。第一次写博客,不怎么会编辑,将就着看先。因为时间不够,内容也不详细,之后慢慢补充完整。
使用Windbg调试StackOverflowException异常
标签:
原文地址:http://www.cnblogs.com/qiups/p/5654544.html