COM+对象池组件
崩溃调试手记
版本
|
创建时间
|
创建人
|
备注
|
1.0.0.1
|
2003-7-20
|
郑 昀
|
第一稿
|
|
|
|
|
本文档将说明XMsg II组件在COM+应用中面对高频率的并发调用发生了崩溃,崩溃地址在NTDLL.DLL内。以及调试的过程。
继续阅读之前,我们假设您熟悉以下知识:
n n Exception Monitor
n n 进程映像转储
n n W32dasm
如果有Windows XP Symbols,那么我们也许会更快找到NTDLL.DLL的崩溃函数。
XMsg II组件是一个COM+对象池组件,线程模型是MTA。当它被COM+激活时,它会先去读取本地配置XML文件,得到相关的启动参数。然后,用户调用它的接口方法发送。最后,用户调用它的GetResponse方法得到 Response XML文档。
1:
XMsg II组件的调用不频繁的时候,并没有出现崩溃。
2:
我制作了一个testXMsg.asp页面,模拟服务器调用XMsg.Dll;
我制作了一个Windows Console Application(TestXMsg.ASP.exe),模拟200个线程并发向发起HTTP POST请求;
而XMsg II组件所在的COM+应用Tomo_X,会在所有调用结束三分钟之后,自动关闭COM+应用,结束这个DLLHOST.EXE进程。
在整个TestXMsg.ASP.exe运行过程中,没有出现任何崩溃。但是在事隔三分钟之后,崩溃出现。
在反复测试TestXMsg.ASP.exe的时候,最大的问题重现崩溃必须有以下要素:
n n 组件在COM+应用中;
n n 组件的接口启用了对象池;
n n 并发调用。
这样有以下难点:
n n 很难用VC IDE进行跟踪。其实,单元测试的时候,用BounsChecker并没有查出问题,组件实例释放的时候也很顺利。
n n 很难从Trace Log中看到有价值的信息。几百个调用并发调用,而且崩溃是在NTDLL.DLL中。
这种进入运行中的COM+应用的调试,最好的工具就是Microsoft Exception Monitor 7.0了。
它可以跟踪进入各种Windows服务运行实例,其中最重要的两个服务是:
þ þ Microsoft Internet Information Service (In Process)
þ þ COM+ Application / MTS Package / IIS (Pooled/Out Of Process)
我们选择监视“COM+ Application / MTS Package / IIS (Pooled/Out Of Process)”。你会看到以下对话框,列出了可供监视的所有COM+进程外应用:
选择我们的“Tomo_UM_X”COM+应用。
在下面的“Start Monitoring”对话框中,点击“Run This Monitoring Session”按钮:
这样,就会启动WinDBG Debugger,Attach到Tomo_X应用实例上。如下图所示:
之后,静静等待COM+应用在三分钟之后的自动关闭应用了。那一刻,WinDBG屏幕上一阵狂闪,然后消失,只留下了Exception Monitor的“Session Status”对话框,如下所示:
你可以选择最近的那个日志,然后点击“View Log”按钮,如下所示:
首先,我们来查看“P.T.C”报告了什么:
***** Activity prior to crash *****
……….
Thread Terminate: Process=0, Thread=11, Exit Code=0
Thread Terminate: Process=0, Thread=6, Exit Code=0
First chance exception c0000005 (Access Violation) occurred
Thread stopped.
它基本上打印出了崩溃之前的DEBUG OUTPUT的内容。
这个“Report”是Exception Monitor一个很强悍的功能,看看它都能告诉我些什么:
***********************************************************
* Exception Monitor Log Analyzer Report version 7.0.0.0
* Report Created from: f:\Program Files\Exception Monitor 7.1\bin\em\logs\OOP_5456-15335-719-2003.dbl
* Report Created on: July 20,2003 at 05:49 PM
* The following fault type was detected: Access Violation
* Exception Monitor 7.1.2195.5
* Log generated on: 2003-7-19 15:04:23
***********************************************************
The service faulted in thread # 15
The stack for the faulting thread follows. Column 1 shows the Child EBP, Column 2 shows the Return Address, Column 3 shows the module called, and column 4 shows the resolved name if column 3 was not able to locate or use symbols. To read the stack, start at the bottom and work your way up. The function on the bottom called the function above it, which called the function above it, etc.
0000000000c6fce4 0000000077f58cca ntdll!0x0000000077F83AED (No FPO)
0000000000c6fdb8 0000000077190729 ntdll!0x0000000077F58CCA (No FPO)
0000000000000001 0000000000000000 ole32!0x0000000077190729 (No FPO)
*****
The following is extended information from the log:
00c6fcd8 : 00080000
00c6fcdc : 000e78a8
00c6fce0 : 00000000
00c6fce4 : 00c6fdb8
00c6fce8 : 77f58cca : C:\WINDOWS\System32\ntdll.dll+0x8cca
00c6fcec : 00080000
……
!inetdbg.ds c6fd98 to dump next block
……………..
……………….
…………………..
…………..
由于没有Windows XP Symbols,Exception Monitor并不能如愿地告诉你崩溃到底发生在哪一个函数,虽然我们知道是NTDLL.DLL的0x77f83aed指令。
NTDLL.DLL的“0x77f83aed”指令可能是什么方面的函数调用呢?
我们用W32dasm加载了NTDLL.DLL,它会进行Disassemble,我们可以看到输出的函数,如下图所示:
从指令地址来看,“0x77f83aed”指令似乎是RtlFreeHeap附近,总之都是涉及释放堆栈。
Windows XP的Component Service提供了一种新功能“进程映像转储”。
通过将 COM+ 应用程序失败时的状态转储到指定目录中,进程转储工具允许管理员简化开发人员调试应用程序的任务。以下是失败情况的例子:
在所有这些情况中,进程转储功能允许转储失败时的整个进程状态,启用更为有效的应用程序失败调试。
这个设置针对某一个COM+应用,如下图所示:
这样,当Tomo_UM_X应用自动关闭时发生的崩溃,就会被COM+把进程映像转储到指定的目录中,存储的文件名类似于:
{424102D6-D93F-42D8-98A4-E39ADDD8DD32}_2003_07_20_11_51_02.dmp
可以用Microsoft Visual Studio .NET打开这个文件,然后“启动新实例”,就可以重现当时的情景,如下所示:
本文档所包含的信息代表了在发布之日,zhengyun对所讨论问题的当前看法。本文档不应理解为zhengyun一方的承诺,zhengyun不保证所给信息在发布之日以后的准确性。
本文档仅供参考。
用户必须遵守所有适用的版权法。在不对版权法所规定的权利加以限制的情况下,如未得到 zhengyun和CSDN.Net明确的书面许可,不得出于任何目的、以任何形式或手段(电子的、机械的、影印、录制等等)复制、传播本文的任何部分,也不得将其存储或引入到检索系统中。
Written by zhengyun (at) tomosoft.com
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=12722