用一行代码让w3wp进程崩溃,如何查找w3wp进程崩溃的原因
2009-12-20 20:29
483 查看
W3wp进程崩溃了,在系统日志中留下了一个错误,而留下的错误信息却很少,如何才能快速查找w3wp崩溃的原因呢?
首先,我们来写一行代码让w3wp崩溃:
viewsource
print?
这一行代码就会让w3wp进程崩溃,因为asp.net2.0之后,微软处理多线程操作异常的默认方式发生了变化,如果在Thread,或者ThreadPool,或者System.Threading.Timer中执行方法中出现未处理异常,则当前执行进程会停止执行崩溃。
当然实际情况中我们不会故意写这么一行代码让w3wp崩溃,也许你会说,我一般情况下不在web程序中使用Thread,或者ThreadPool,即便如此,出现崩溃也是有可能的,因为数据库的连接池,HttpRuntime管理请求队列等系统方法中也会用到Thread,或者System.Threading.Timer类,或者ThreadPool。我曾经亲身遭遇到系统方法导致崩溃,是因为sqlserver的数据库连接池被耗尽,取不出新的数据库连接而导致崩溃,这和以上一行代码导致崩溃的原理是一样的。
可以这么说这种崩溃是一种微软设计的应该崩溃的情况,微软认为如果在多线程中执行过程中发生异常就应该让进程崩溃。而这种崩溃发生之后留下的系统日志往往很少,我们只能看到崩溃的错误,而得不到崩溃的具体点或者崩溃发生的调用堆栈。俗话说:“办法总比苦难多”,虽然系统没有记录,但是我们可以通过代码来让系统记录崩溃原因。我们有两种办法来得到崩溃原因。
第一种办法是利用反射在Global的Application_End事件中记录HttpRuntime的退出堆栈和退出原因。如果你手头有反编译的工具,你可以反编译一下System.Web.HttpRuntime类,你可以看到此类有两个私有的字段:
viewsource
print?
他们记录了w3wp进程的退出消息和退出堆栈,通常我们在Application_End事件中记录这两个变量的值,就可以看到崩溃的堆栈。具体怎么做请看代码
viewsource
print?
以上代码主要使用了反射,本文不做详细解释。
上面的这种方法通常情况可以得到w3wp崩溃的调用堆栈,我们还有另一种方法来获得。利用AppDomain.CurrentDomain.UnhandledException事件来记录未处理异常的发生原因,代码也很简单:
viewsource
print?
以上代码的是在ApplicationStart的时候给AppDomain的UnhandleException时间加处理方法,来记录未处理异常的发生原因。
首先,我们来写一行代码让w3wp崩溃:
1 | protected void Page_Load( object sender,EventArgse) |
2 | { |
3 | ThreadPool.QueueUserWorkItem( delegate ( object noUse){ throw new Exception( "gotohellw3wp!" );}); |
4 | } |
当然实际情况中我们不会故意写这么一行代码让w3wp崩溃,也许你会说,我一般情况下不在web程序中使用Thread,或者ThreadPool,即便如此,出现崩溃也是有可能的,因为数据库的连接池,HttpRuntime管理请求队列等系统方法中也会用到Thread,或者System.Threading.Timer类,或者ThreadPool。我曾经亲身遭遇到系统方法导致崩溃,是因为sqlserver的数据库连接池被耗尽,取不出新的数据库连接而导致崩溃,这和以上一行代码导致崩溃的原理是一样的。
可以这么说这种崩溃是一种微软设计的应该崩溃的情况,微软认为如果在多线程中执行过程中发生异常就应该让进程崩溃。而这种崩溃发生之后留下的系统日志往往很少,我们只能看到崩溃的错误,而得不到崩溃的具体点或者崩溃发生的调用堆栈。俗话说:“办法总比苦难多”,虽然系统没有记录,但是我们可以通过代码来让系统记录崩溃原因。我们有两种办法来得到崩溃原因。
第一种办法是利用反射在Global的Application_End事件中记录HttpRuntime的退出堆栈和退出原因。如果你手头有反编译的工具,你可以反编译一下System.Web.HttpRuntime类,你可以看到此类有两个私有的字段:
1 | private string _shutDownMessage; |
2 | private string _shutDownStack; |
01 | protected void Application_End( object sender,EventArgse) |
02 | { |
03 | HttpRuntimeruntime=(HttpRuntime) typeof (System.Web.HttpRuntime).InvokeMember( "_theRuntime" , |
04 | BindingFlags.NonPublic|BindingFlags.Static|BindingFlags.GetField, |
05 | null , |
06 | null , |
07 | null ); |
08 |
09 | if (runtime== null ) |
10 | return ; |
11 |
12 | string shutDownMessage=( string )runtime.GetType().InvokeMember( "_shutDownMessage" , |
13 | BindingFlags.NonPublic|BindingFlags.Instance|BindingFlags.GetField, |
14 | null , |
15 | runtime, |
16 | null ); |
17 |
18 | string shutDownStack=( string )runtime.GetType().InvokeMember( |
19 | "_shutDownStack" , |
20 | BindingFlags.NonPublic|BindingFlags.Instance|BindingFlags.GetField, |
21 | null , |
22 | runtime, |
23 | null ); |
24 |
25 | if (!EventLog.SourceExists( ".NETRuntime" )) |
26 | { |
27 |
28 | EventLog.CreateEventSource( ".NETRuntime" , "Application" ); |
29 |
30 | } |
31 |
32 | EventLoglog= new EventLog(); |
33 |
34 | log.Source= ".NETRuntime" ; |
35 |
36 | log.WriteEntry(String.Format( "\r\n\r\n_shutDownMessage={0}\r\n\r\n_shutDownStack={1}" ,shutDownMessage,shutDownStack),EventLogEntryType.Error); |
37 | } |
上面的这种方法通常情况可以得到w3wp崩溃的调用堆栈,我们还有另一种方法来获得。利用AppDomain.CurrentDomain.UnhandledException事件来记录未处理异常的发生原因,代码也很简单:
01 | protected void Application_Start( object sender,EventArgse) |
02 | { |
03 | AppDomain.CurrentDomain.UnhandledException+= new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); |
04 | } |
05 |
06 | void CurrentDomain_UnhandledException( object sender,UnhandledExceptionEventArgse) |
07 | { |
08 | Exceptionex=e.ExceptionObject as Exception; |
09 | string msg=ex.Message; |
10 | string stack=ex.StackTrace; |
11 | } |
相关文章推荐
- 用一行代码让w3wp进程崩溃,如何查找w3wp进程崩溃的原因
- 用一行代码让w3wp进程崩溃,如何查找w3wp进程崩溃的原因
- 用一行代码让w3wp进程崩溃,如何查找w3wp进程崩溃的原因
- 71.iOS 错误堆栈查找崩溃原因的方法---根据崩溃信息,找到对应的崩溃代码
- [小技巧] 如何在 git 里查找哪一个 commit 删除了代码的一行
- VS 2005使用map文件查找程序崩溃原因
- 原因以及如何避免产生僵尸进程
- 如何用一行C++代码读写数据库
- 替换TXT文件里的字符串,一行一行查找替换,java代码
- 在.NET中,如何查找一个进程的父进程
- 如何通过崩溃地址找到出错的代码行(ZT)
- linux如何根据进程ID查找启动程序的路径
- iOS错误堆栈查找崩溃原因的方法
- iOS从crash信息中查找崩溃原因
- 如何使用MAP文件找到程序崩溃的原因
- ps如何通过进程名来查找进程号
- 一行能让IE6崩溃的简单HTML和CSS代码
- VS2005(vs2008,vs2010)使用map文件查找程序崩溃原因
- 一行代码设置本进程的oracle客户端字符集
- 如何定位Sharepoint网站集所在的w3wp进程