gpt4 book ai didi

c# - 如何调试 C# 托管/非托管编码异常?

转载 作者:太空狗 更新时间:2023-10-29 23:26:05 27 4
gpt4 key购买 nike

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

目前我有:DirectShow.dll 中出现类型为“System.NullReferenceException”的异常(这是我的托管 dll 的名称),并且未在托管/ native 边界之前处理

调用堆栈:

ntdll.dll!NtWaitForSingleObject() + 0xa bytes
KernelBase.dll!WaitForSingleObjectEx() + 0x9c bytes
clr.dll!CLREvent::WaitEx() + 0x20f bytes
clr.dll!CLREvent::WaitEx() + 0x1b8 bytes
clr.dll!CLREvent::WaitEx() + 0x73 bytes
clr.dll!Thread::WaitSuspendEventsHelper() + 0xcf bytes clr.dll!Thread::WaitSuspendEvents() + 0x10 bytes
clr.dll!string "d:\iso_whid\amd64fre\base\ntos\r"...() + 0x35688d bytes
clr.dll!Thread::RareDisablePreemptiveGC() + 0x118 bytes
clr.dll!GCHolderEEInterface<0,0,0>::~GCHolderEEInterface<0,0,0>() + 0x19 bytes clr.dll!Debugger::SendCatchHandlerFound() + 0x150 bytes
clr.dll!string "d:\iso_whid\amd64fre\base\ntos\r"...() + 0x3b9340 bytes
clr.dll!NotifyOfCHFFilterWrapper() + 0x77 bytes
clr.dll!string "d:\iso_whid\amd64fre\base\ntos\r"...() + 0x336941 bytes
msvcr100_clr0400.dll!__C_specific_handler() + 0x97 bytes
ntdll.dll!RtlpExecuteHandlerForException() + 0xd bytes ntdll.dll!RtlDispatchException() + 0x38f bytes ntdll.dll!KiUserExceptionDispatch() + 0x2e bytes
KernelBase.dll!RaiseException() + 0x3d bytes
clr.dll!NakedThrowHelper2() + 0xc bytes
clr.dll!NakedThrowHelper_RspAligned() + 0x3d bytes clr.dll!NakedThrowHelper_FixRsp() + 0x5 bytes
000007ff00179486()
clr.dll!COMToCLRDispatchHelper() + 0x4e bytes
clr.dll!SecurityDeclarative::CheckLinkDemandAgainstAppDomain() - 0x40e bytes
clr.dll!COMToCLRWorkerBody() + 0xd6 bytes
clr.dll!COMToCLRWorkerDebuggerWrapper() + 0x22 bytes
clr.dll!COMToCLRWorker() + 0x201 bytes clr.dll!GenericComCallStub() + 0x57 bytes
[Native to Managed Transition]
quartz.dll!CEnumConnectedPins::CEnumConnectedPins() + 0x4a bytes
quartz.dll!CFilterGraph::FindUpstreamInterface() + 0x150 bytes quartz.dll!CFilterGraph::FindUpstreamInterface() + 0xc1 bytes
quartz.dll!CFilterGraph::FindUpstreamInterface() + 0x171 bytes quartz.dll!CFilterGraph::FindUpstreamInterface() + 0xc1 bytes
quartz.dll!CFilterGraph::FindUpstreamInterface() + 0x171 bytes quartz.dll!CFilterGraph::FindUpstreamInterface() + 0xc1 bytes
quartz.dll!CWaveSlave::UpdateSlaveMode() + 0xa7 bytes
quartz.dll!CWaveOutInputPin::RemovePreroll() + 0x95 bytes
quartz.dll!CWaveOutInputPin::Receive() + 0x12f bytes
msmpeg2adec.dll!CBaseOutputPin::Deliver() + 0x22 bytes msmpeg2adec.dll!CIVIAudioFilter::DeliverOutSample() + 0x3da bytes
msmpeg2adec.dll!CIVIAudioCodec::DecodeDDPlus() + 0x556 bytes
msmpeg2adec.dll!CIVIAudioCodec::DecodeAll() + 0x121 bytes
msmpeg2adec.dll!CIVIAudioFilter::Process() + 0xda7 bytes
msmpeg2adec.dll!CIVIAudioFilter::Receive() + 0x16d bytes
msmpeg2adec.dll!CTransformInputPin::Receive() + 0x4c bytes msmpeg2adec.dll!CIVIAudioInPin::Receive() + 0x3f bytes quartz.dll!CBaseOutputPin::Deliver() + 0x22 bytes
quartz.dll!CBaseMSRWorker::TryDeliverSample() + 0x14f bytes
quartz.dll!CBaseMSRWorker::PushLoop() + 0x1da bytes
quartz.dll!CBaseMSRWorker::ThreadProc() + 0x90 bytes
quartz.dll!CAMThread::InitialThreadProc() + 0x1c bytes kernel32.dll!BaseThreadInitThunk() + 0xd bytes ntdll.dll!RtlUserThreadStart() + 0x21 bytes

换句话说,管道是:

  1. 名为 CEnumConnectedPins() 的 native 代码函数
  2. native 到托管的转换 -> 如果此处抛出异常,则第 3 步中的 xxx 只有编码程序知道,但我们处于未知状态。
  3. 名为 xxx 的托管代码方法。

所以这对我没有任何帮助,我不知道如何调试它。

最佳答案

调试起来非常难看,错误发生在您未编写的代码中。慢一点来诊断这个。编写一个 native 测试程序,获取要测试的接口(interface)指针,并按照v-table顺序逐一验证方法。坏的会跳出来。

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

关于c# - 如何调试 C# 托管/非托管编码异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6573676/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com