如何调试C#托管/非托管封送异常?

如何调试C#托管/非托管封送异常?,c#,debugging,com,interop,marshalling,C#,Debugging,Com,Interop,Marshalling,我正在C#上编写DirectShow过滤器,我不想使用任何第三方库。此任务几乎100%基于COM接口(如IGraphBuilder、IBaseFilter、IPin等)的正确原型。如果接口原型不正确,则会在托管/本机边界引发各种异常。问题是确定不正确的原型接口方法的位置 目前我有: DirectShow.dll(这是我的托管dll的名称)中发生“System.NullReferenceException”类型的异常,在托管/本机边界之前未处理该异常 调用堆栈: ntdll.dll!NtWaitF

我正在C#上编写DirectShow过滤器,我不想使用任何第三方库。此任务几乎100%基于COM接口(如IGraphBuilder、IBaseFilter、IPin等)的正确原型。如果接口原型不正确,则会在托管/本机边界引发各种异常。问题是确定不正确的原型接口方法的位置

目前我有: DirectShow.dll(这是我的托管dll的名称)中发生“System.NullReferenceException”类型的异常,在托管/本机边界之前未处理该异常

调用堆栈:

ntdll.dll!NtWaitForSingleObject()+0xa字节
KernelBase.dll!WaitForSingleObjectEx()+0x9c字节
clr.dll!CLREvent::WaitEx()+0x20f字节
clr.dll!CLREvent::WaitEx()+0x1b8字节
clr.dll!CLREvent::WaitEx()+0x73字节
clr.dll!线程::WaitSuspendEventHelper()+0xcf字节 clr.dll!线程::WaitSuspendEvents()+0x10字节
clr.dll!字符串“d:\iso\u whid\amd64fre\base\ntos\r”…()+0x35688d字节
clr.dll!线程::raredisablepremptivegc()+0x118字节
clr.dll!GCHolderEEInterface::~GCHolderEEInterface()+0x19字节 clr.dll!调试器::SendCatchHandlerFound()+0x150字节
clr.dll!字符串“d:\iso_whid\amd64fre\base\ntos\r”…()+0x3b9340字节
clr.dll!notifyOfchfilterRapper()+0x77字节
clr.dll!字符串“d:\iso\u whid\amd64fre\base\ntos\r”…()+0x336941字节
msvcr100_clr0400.dll__C_特定的_处理程序()+0x97字节
ntdll.dll!RtlpExecuteHandlerForException()+0xd字节 ntdll.dll!RtlDispatchException()+0x38f字节 ntdll.dll!KiUserExceptionDispatch()+0x2e字节
KernelBase.dll!RaiseException()+0x3d字节
clr.dll!NakedThrowHelper2()+0xc字节
clr.dll!nakedthrowhelperrspaigned()+0x3d字节 clr.dll!NakedThrowHelper_FixRsp()+0x5字节
000007ff00179486()
clr.dll!COMToCLRDispatchHelper()+0x4e字节
clr.dll!SecurityDeclarative::CheckLinkDemandAgainstAppDomain()-0x40e字节
clr.dll!COMToCLRWorkerBody()+0xd6字节
clr.dll!COMToCLRWorkerDebuggerWrapper()+0x22字节
clr.dll!COMToCLRWorker()+0x201字节 clr.dll!GenericComCallStub()+0x57字节
[本机到托管转换]
quartz.dll!CEnumConnectedPins::CEnumConnectedPins()+0x4a字节
quartz.dll!CFilterGraph::FindUpstreamInterface()+0x150字节 quartz.dll!CFilterGraph::FindUpstreamInterface()+0xc1字节
quartz.dll!CFilterGraph::FindUpstreamInterface()+0x171字节 quartz.dll!CFilterGraph::FindUpstreamInterface()+0xc1字节
quartz.dll!CFilterGraph::FindUpstreamInterface()+0x171字节 quartz.dll!CFilterGraph::FindUpstreamInterface()+0xc1字节
quartz.dll!CWaveSlave::UpdateSlaveMode()+0xa7字节
quartz.dll!CWaveOutInputPin::RemovePreroll()+0x95字节
quartz.dll!CWAVEOUTIPUTPIN::Receive()+0x12f字节
msmpeg2adec.dll!CBaseOutputPin::Deliver()+0x22字节 msmpeg2adec.dll!CIVIAudioFilter::DeliverOutSample()+0x3da字节
msmpeg2adec.dll!CIVIAudioCodec::decodedPlus()+0x556字节
msmpeg2adec.dll!CIVIAudioCodec::DecodeAll()+0x121字节
msmpeg2adec.dll!CIVIAudioFilter::Process()+0xda7字节
msmpeg2adec.dll!CIVIAudioFilter::Receive()+0x16d字节
msmpeg2adec.dll!CtrTransformInputPin::Receive()+0x4c字节 msmpeg2adec.dll!CIVIAudioInPin::Receive()+0x3f字节 quartz.dll!CBaseOutputPin::Deliver()+0x22字节
quartz.dll!CBaseMSRWorker::TryDeliverSample()+0x14f字节
quartz.dll!CBaseMSRWorker::PushLoop()+0x1da字节
quartz.dll!CBaseMSRWorker::ThreadProc()+0x90字节
quartz.dll!CAMThread::InitialThreadProc()+0x1c字节 内核32.dll!BaseThreadInitThunk()+0xd字节 ntdll.dll!RtlUserThreadStart()+0x21字节

换句话说,管道是:

  • 名为CEnumConnectedPins()的本机代码函数
  • 托管托管转换> >如果抛出异常,则XXX从步骤3只知道封送器,但我们处于无处。
  • 名为xxx的托管代码方法
  • 所以这对我来说毫无意义,我也不知道如何调试它。

    调试起来非常难看,失败发生在你没有编写的代码中。请放慢诊断速度。编写一个本机测试程序,以v表顺序逐个获取要测试和验证方法的接口指针。坏的会跳出来


    请注意,C#不支持多重继承。任何从非IUnknown或IDispatch的另一个接口继承的COM接口都需要在基接口中重复方法的声明。忘记这样做会导致调用错误的方法。或者不存在,因为v形表太短。NullReference或AccessViolation是常见的结果。

    那么你有没有想过?