月度归档:2010年08月

一个网站崩溃问题的解决方法之总结

问题

公司的网站(ASP .NET MVC的架构) 频繁重启,甚至超过进程池的快速失败保护,导致Service Unavailable。

在自己的日志里,只有重启的记录,没法查到哪里出的错。看IIS日志,也没看出什么来。

事件查看器里面,重启的时候有下面的描述:

EventType clr20r3, P1 w3wp.exe, P2 6.0.3790.3959, P3 45d6968e, P4 system.data.linq, P5 3.5.0.0, P6 488ef99a, P7 92c, P8 0, P9 system.stackoverflowexception, P10 NIL.

可以看出来,是某个地方stack overflow了,但具体是哪里,事件查看器也没有记录堆栈信息(是不是因为太大了,无法记录?)

抓dump文件

希望出异常时能够将堆栈转储出来。原来做C++的时候,比较清楚注册表里AeDebug (HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\Current Version\AeDebug) 的设置,看了看是vsjitdebugger.exe,这是因为这台机器上最早装过vs 2005。可是这个vsjitdebugger是弹出提示的,并没有转储信息。

删除之,用drwtsn32 -i,注册了dr. watson,以前都是用这个转储的。但发现崩溃后,并没有转储东西。搜了搜,发现这个只是用来处理非托管代码的(比如C++),而托管代码需要再另一个注册表项里面: HKEY_LOCAL_MACHINE\Software\Microsoft\.NETFramework\DbgJITDebugLaunchSetting和DbgManagedDebugger。

看了看这两个设置: DbgJITDebugLaunchSetting = 0x10, DbgManagedDebugger = vsjitdebugger.exe。看了下进程管理器中,居然有了300多个vsjitdebugger.exe进程。把vsjitdebugger.exe进程全部杀掉,注册表里面的DbgManagedDebugger也给干掉了。

这时候,崩溃时不会再出vsjitdebugger.exe进程了。但事件管理器中会出现新的错误:

事件 ID ( 0 )的描述(在资源( .NET Runtime )中)无法找到。本地计算机可能没有必要的注册信息或消息 DLL 文件来从远程计算机显示消息。您可能可以使用 /AUXSOURCE= 标识来检索词描述;查看帮助和支持以了解详细信息。下列信息是事件的一部分: .NET Runtime version : 2.0.50727.3603 – 未找到调试器。未指定注册的 JIT 调试程序。 单击”重试”使进程处于等待状态,此时可手动附加调试器。 单击”取消”可中止 JIT 调试请求。

这个无所谓,找不到DbgManagedDebugger了嘛,把DbgJITDebugLaunchSetting 改个其它值也就行了。可是我想转储啊,这里有什么可以转储了。

主角出现:下载Debugging Tools For Windows. 安装。然后将jitdebugger设为cdb.exe (其实这里只需要托管代码的,AeDebug只是顺手),将错误转储到c:\crash_dumps下。运行下面的reg文件即可:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
“DbgManagedDebugger”=”\”c:\\debuggers\\x86\\cdb.exe\” -pv -p %ld -c \”.dump /u /ma c:\\crash_dumps\\crash.dmp;.kill;qd\””
“DbgJITDebugLaunchSetting”=dword:00000002
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug]
“Debugger”=”\”c:\\debuggers\\x86\\cdb.exe\” -pv -p %ld -c \”.dump /u /ma c:\\crash_dumps\\crash.dmp;.kill;qd\”” “Auto”=”1”

如果是64位机器呢,则上面是x64目录下的cdb,再将[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework]和[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug]下面的相应项设为x86的。

好了,抓到dump文件了。

查看dump文件

用windbg来打开。记住先设置好Symbol File的目录: D:\TXWap_Work\www\TXWap\bin; c:\symbols; srv*c:\symbols*http://msdl.microsoft.com/download/symbols

前面的是自己本地的工作目录,下面有自己DLL相应的pdb。而后面的是说系统没有的话,到某个网站去下载符号文件。

然后再windbg中打开dump文件。

在windbg中要调试托管代码,需要加载一个调试器扩展SOS(Son of Strike),这个工具在Debugging Tools For Windows里面就有了。因此只要下面这样加载SOS.dll:

.loadby sos mscorwks

然后看所有的线程:

!threads

PreEmptive GC Alloc Lock
   ID OSID ThreadOBJ State GC Context Domain Count APT Exception
   20 1 3210 000dc110 1808220 Enabled 00000000:00000000 00105678 1 MTA (Threadpool Worker)
   31 2 4430 000e9fa0 b220 Enabled 04d9213c:04d93f5c 000ccbc0 0 MTA (Finalizer)
   32 3 3190 00100d48 80a220 Enabled 00000000:00000000 000ccbc0 0 MTA (Threadpool Completion Port)
   33 4 fc4 00102f00 180b220 Enabled 00000000:00000000 00105678 1 MTA (Threadpool Worker)
   34 5 15a4 00104c60 1220 Enabled 00000000:00000000 000ccbc0 0 Ukn
   35 6 30dc 001178f0 180b220 Enabled 0d303d20:0d304e60 00105678 1 MTA (Threadpool Worker)
   36 7 466c 00130a30 180b220 Disabled 0d313ac8:0d314e68 00105678 1 MTA (Threadpool Worker)
   21 8 f64 00151d08 180a220 Disabled 0335d2cc:0335da50 00105678 1 MTA (Threadpool Worker)
   39 9 3010 1b2d5070 180b220 Enabled 093004c4:0930057c 00105678 1 MTA (Threadpool Worker) System.StackOverflowException (0ecf00a4)
   41 a 28f0 1b2e2778 180b220 Disabled 11414e0c:11415924 00105678 1 MTA (Threadpool Worker)
   42 b 2174 1b2e2b70 380b220 Enabled 00000000:00000000 00105678 0 MTA (Threadpool Worker)
   43 c 35f4 1b2e3478 180b220 Enabled 11124dd8:111254d8 00105678 1 MTA (Threadpool Worker)
   44 d 1b98 1b2e40e8 180b220 Enabled 032e0e28:032e1a50 00105678 1 MTA (Threadpool Worker)
   45 e c98 1b2e4ac8 380b220 Enabled 00000000:00000000 00105678 0 MTA (Threadpool Worker)
   46 f 23e4 1b2e5608 180b220 Disabled 09300c70:0930257c 00105678 1 MTA (Threadpool Worker)
   47 10 2764 1b2e6148 380b220 Enabled 00000000:00000000 00105678 0 MTA (Threadpool Worker)
   48 11 2318 1b2e6c88 180b220 Disabled 0b3e4124:0b3e5dc8 00105678 1 MTA (Threadpool Worker)
   49 12 1cbc 1b2e77c8 380b220 Enabled 00000000:00000000 00105678 0 MTA (Threadpool Worker)
   50 13 560 1b2e8338 180b220 Enabled 0b3707ac:0b3719d0 00105678 1 MTA (Threadpool Worker)
   51 14 45c0 1b2e8ea8 180b220 Enabled 0917eacc:0918057c 00105678 1 MTA (Threadpool Worker)
   52 15 28e4 1b2e9a90 180b220 Enabled 07281228:07283190 00105678 1 MTA (Threadpool Worker)
   18 16 17a0 1b2d7fc0 180a220 Enabled 00000000:00000000 000ccbc0 0 MTA (Threadpool Worker)
   53 17 2f94 1b383e38 380b220 Enabled 00000000:00000000 00105678 0 MTA (Threadpool Worker)
   XXXX 18 9c8 1e853958 80010220 Enabled 00000000:00000000 000ccbc0 0 Ukn
   

看到了哪个线程有异常了吗?切换到39线程:

~39s

看堆栈:

!clrstack

可以看到堆栈列表。定位到是我们哪个函数出的问题,后面的事情就好办了 🙂

入手一部HTC Desire G7

用起来还是挺爽的。有点小遗憾就是是个阿拉伯版的,有些预装程序还删不掉,看着《古兰经》什么的怪怪的,啥时候刷掉它。