【发布时间】:2012-08-24 13:40:34
【问题描述】:
我在一个经典的 ASP Web 应用程序上工作,它使用了几个用 VB6 编写的旧 COM 组件。所有 VB6 组件都在 COM+ 应用程序中注册,这些应用程序在它们自己的 dllhost 进程中运行。大部分应用程序已转换为 .Net,但仍有许多遗留页面和组件。 COM Interop 用于两个方向,从经典的 ASP 和 VB6 调用一些 .Net 程序集以及从 ASP.Net 调用 VB6 组件。该应用程序在 Windows Server 2008 R2 (IIS 7.5) 上以经典管道模式运行。
在大多数情况下,应用程序运行良好。最终放弃了向 .Net 的过渡,取而代之的是开发了一种新产品。同时,旧产品必须保持在异构状态。
我无法跟踪网络应用程序挂起的间歇性问题。用户在浏览器等待时只会看到一个空白屏幕,而服务器从不响应。挂起一直存在,直到我手动终止托管 VB6 组件的 dllhost 进程,所以我相信问题就在那里。可能是内存泄漏或失控的循环循环。
系统每天有成千上万的用户,但问题每周只发生一两次。幸运的是,我们有一个网络农场,它会在服务器停止响应时自动将其拉出,因此对客户的影响为零。不过,我想弄清楚发生了什么。
我已重新编译所有 VB6 组件以包含调试符号并重新部署到生产环境。当问题发生时,我使用 32 位任务管理器 (c:\windows\syswow64\taskmgr.exe) 对 dllhost 进程进行故障转储。我最终得到了一个 dllhost.dmp 文件,我将它带到我的开发工作站并在 VS2010 中打开。我有 VB6 在我的符号路径中创建的 .pdb 符号文件。当我在 VS2010 中启动调试会话时,我可以进入 Modules 屏幕并看到确实加载了我的组件的所有符号。
从这里去哪里?调用堆栈没有显示我自己的任何组件。它看起来像这样:
调用堆栈顶部的反汇编如下所示:
不知道我还能做什么。我检查了调用堆栈的每一帧的所有本地人,这对我来说是胡言乱语。我没有看到对我自己的任何组件的任何引用。
也许 WinDbg 会产生更多信息?不知道从哪里开始。
我很确定,如果我能找到挂起发生时调用的 VB6 类/方法,我就能找到它的底部。我尝试添加一些日志记录,结果不一致。
也许我的 VB6 组件完全没有问题,但我遇到了 Windows 或 IIS 中的一些错误?
我们将不胜感激任何建议,但目前不能选择放弃 VB6。谢谢。
【问题讨论】:
-
您是否在打开
Unattended Execution和Retained In Memory的情况下编译了您的VB6 组件?在 COM+ 下使用全局变量非常容易泄漏——如果可能,尝试转换为无状态类。 -
是的,这两个都打开了。除了常量之外,没有太多的全局变量。我会看看我能不能把这些因素排除在外。
标签: com asp-classic vb6 windbg com-interop