【问题标题】:Unreleased DirectShow CSource filter makes program crash at process shutdown未发布的 DirectShow CSource 过滤器使程序在进程关闭时崩溃
【发布时间】:2012-09-06 07:57:23
【问题描述】:

我正在开发 DirectShow CSource 捕获过滤器。它工作正常,但是当我关闭使用过滤器的程序时(在这种情况下,我正在使用 VLC 进行测试,但其他程序也会发生同样的情况),程序崩溃(如果我在 Visual Studio 中调试它,那么断点被触发)。

我一直在寻找这个问题一段时间,发现我的源过滤器和源流都没有被释放;也就是说,它们的引用计数器在程序结束时为 1,DllCanUnloadNow() 函数报告有 2 个对象仍在使用中,当调用 CoUninitialize() 时,程序崩溃。

我很确定引用计数器得到了正确处理,因为我使用的是基类实现。我能想到的软件中唯一不寻常的事情是我使用的是我自己的 DllGetClassObject() 版本:我将 .DEF 文件配置为导出 MyDllGetClassObject() 而不是 DllGetClassObject(),因此我可以在之前插入一些代码调用默认实现。我认为这不是问题,因为我检查了在 MyDllGetClassObject() 末尾返回的所有对象的引用计数器是否为 1。

我想我遗漏了有关过滤器生命周期的一些信息,但不知道是什么(这是我正在开发的第一个捕获过滤器)。有什么建议吗?

提前谢谢你,

吉列尔莫

【问题讨论】:

  • 崩溃/异常时是否有堆栈跟踪?
  • 堆栈跟踪不包含我的任何函数:KernelBase.dll!76c7280c() [下面的帧可能不正确和/或丢失,没有为 KernelBase.dll 加载符号] MyFilters.dll! DbgAssert(const wchar_t *pCondition=0x00540052, const wchar_t * pFileName=0x00460020, int iLine=0x00690061) 第 557 行 + 0x8 字节 C++ 00450053()
  • MyFilters.dll 不是您的代码吗? DbgAssert 表明这是一个调试版本。
  • MyFilters.dll 包含我的代码,但 DbgAssert 是基类的一部分。这是一个调试版本,但在发布版本中也会发生同样的情况。我在DebugBreak 之前设置了一个断点,并且在调用_DllEntryPoint(由DllEntryPoint 调用)期间引发了错误。 _DllEntryPoint 充满了抱怨MyFilters.dll 持有两个活物的消息。我相信我不会在我应该做的地方释放我的对象。我是否必须释放MyDllGetClassObjectIClassFactory 返回的过滤器(这两个都是我实现的)?如果是,我应该在哪里做?
  • DbgAssert 表示您的 DLL 有问题。这是对 COM 指针和引用的不正确操作。您还没有提供任何信息来说明究竟是什么问题。由您来调试,看看哪些项目未发布,可能是什么原因。

标签: com directshow


【解决方案1】:

我终于弄清楚发生了什么。我的源过滤器中的静态方法InitializeInstance 在进程关闭时使用bLoading == falserclsid == <the GUID of my filter> 调用。这似乎是从过滤器实例中释放剩余引用计数器的合适位置。

不久前,我从 StackOverflow 上的另一篇题为 DirectShow code crashes after exit (PushSourceDesktop sample) 的帖子中了解到在 CoUninitialize 之前释放所有 COM 对象的重要性。我所需要的只是多一点关于 DirectShow 过滤器生命周期的知识。

无论如何,谢谢你的努力,Roman,我知道这个线程从一开始就听起来很模糊:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-06
    • 2013-12-12
    • 1970-01-01
    相关资源
    最近更新 更多