调试VB6 COM + Web应用程序挂起

时间:2012-08-29 21:05:55

标签: com asp-classic vb6 windbg com-interop

我在使用几个用VB6编写的旧COM组件的Classic ASP Web应用程序上工作。所有VB6组件都在COM +应用程序中注册,该应用程序在自己的dllhost进程中运行。大部分应用程序已转换为.Net,但仍有许多遗留页面和组件。 COM Interop用于两个方向,从经典ASP和VB6调用一些.Net程序集,以及从ASP.Net调用VB6组件。该应用程序在经典管道模式下在Windows Server 2008 R2(IIS 7.5)上运行。

在大多数情况下,应用程序运行正常。最终放弃了向.Net努力的过渡,而开发了一种新产品。与此同时,旧产品必须保持其异构状态。

我无法跟踪Web应用程序挂起的间歇性问题。用户只需在浏览器等待时看到空白屏幕,服务器就不会响应。挂起持续存在,直到我手动杀死托管VB6组件的dllhost进程,所以我相信问题埋没在那里。可能是内存泄漏或失控的循环循环。

系统每天有数千名用户,但问题只发生在一周一次或两次。幸运的是,我们有一个Web服务器场,当服务器停止响应时会自动将服务器拉出,因此客户影响为零。不过,我想知道发生了什么。

我已经重新编译了所有VB6组件以包含调试符号并重新部署到生产中。当问题发生时,我使用32位任务管理器(c:\ windows \ syswow64 \ taskmgr.exe)来进行dllhost进程的故障转储。我最终得到了一个dllhost.dmp文件,我把它带到我的开发工作站并在VS2010中打开。我有我的符号路径中创建的VB6 .pdb符号文件。当我在VS2010中启动调试会话时,我可以转到模块屏幕,看看确实已经加载了我组件的所有符号。

从哪里开始?调用堆栈不显示任何我自己的组件。它看起来像这样:

Call Stack

调用堆栈顶部的反汇编如下所示:

Disassembly

不确定我还能做些什么。我检查了调用堆栈每一帧的所有本地人,这对我来说是胡言乱语。我没有看到任何对我自己组件的引用。

也许WinDbg会产生更多信息?不知道从哪里开始。

我很确定如果我能找到挂起发生时调用的VB6类/方法,我可以找到它的底部。我尝试添加一些日志记录,结果不一致。

也许我的VB6组件根本没什么问题,但是我在Windows或IIS中遇到了一些错误?

任何建议都会受到赞赏,但丢掉VB6并不是一个选择。感谢。

1 个答案:

答案 0 :(得分:1)

不是一个完整的答案,但只要代理进程正在运行,就会记录CoRegisterSurrogateEx阻止:

  

CoRegisterSurrogateEx函数是一个阻塞函数。它不是   返回,直到COM +确定该进程将被关闭。   在调用此函数之前,将此线程上的COM初始化为a   多线程公寓(MTA)。

所以我认为错误不在这个调用堆栈上。 (你可以看到它在WaitForSingleObject调用时仍然是阻塞的,很可能是它用来阻塞直到进程被关闭的机制。)