You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinDbg排查C#调用C++ DLL粘贴回调后随机崩溃根因

图片粘贴场景应用崩溃故障分析

故障背景

  • 触发场景:执行图片粘贴操作时,程序调用C++编写的外部DLL实现相关逻辑;流程初始化阶段从C#侧注册回调函数,粘贴操作完成后触发C#侧回调逻辑,回调函数执行结束后应用直接崩溃,异常无法被任何try/catch块捕获
  • 故障特征:随机偶现,无稳定复现路径,相关业务源代码超过2年未做任何变更
  • 待确认问题:初步怀疑堆损坏导致崩溃,需确认故障属于堆泄漏还是堆越界异常,输出对应排查、处理方案

WinDbg崩溃转储原始输出

************* Path validation summary **************
Response                         Time (ms)     Location
Deferred                                       srv*
OK                                             D:\Core\Bin
Symbol search path is: srv*;D:\Core\Bin
Executable search path is: 
Windows 10 Version 19044 MP (8 procs) Free x86 compatible
Product: WinNt, suite: SingleUserTS
Edition build lab: 19041.1.amd64fre.vb_release.191206-1406
Machine Name:
Debug session time: Wed Jul 13 15:55:25.000 2022 (UTC + 5:30)
System Uptime: 0 days 1:21:28.318
Process Uptime: 0 days 0:01:57.000
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
.....................
Loading unloaded module list
.........
For analysis of this file, run !analyze -v
eax=00000000 ebx=00c5e5e8 ecx=00000003 edx=00000000 esi=00000000 edi=000002f4
eip=778129fc esp=0019d0dc ebp=0019d14c iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
ntdll!NtWaitForSingleObject+0xc:
778129fc c20c00          ret     0Ch
0:000> !analyze -v
*******************************************************************************
*                                                                             *
*                        Exception Analysis                                   *
*                                                                             *
*******************************************************************************

*** WARNING: Unable to verify checksum for libcef.dll
*** WARNING: Unable to verify checksum for WindowsBase.ni.dll
*** WARNING: Unable to verify checksum for PresentationCore.ni.dll
*** WARNING: Unable to verify checksum for NextGen.Core.dll
MethodDesc:   45b52128
Method Name:  OnCallBackMethod(IntPtr, IntPtr, UInt32, ART_MARK_ATTRIBUTES, enumModifyReasons)
Class:        45b690fc
MethodTable:  45b52d70
mdToken:      06000242
Module:       1bcc94c4
IsJitted:     yes
CodeAddr:     09061a00
Transparency: Critical
Source file:  D:\Core\PasteImage.cs @ 724
MethodDesc:   476ed6a8
Method Name:  DomainBoundILStubClass.IL_STUB_ReversePInvoke(Int32, Int32, Int32, IntPtr, Int32)
Class:        07d51b3c
MethodTable:  07d51b90
mdToken:      06000000
Module:       00874044
IsJitted:     yes
CodeAddr:     47773910
Transparency: Safe critical
Failed to request MethodData, not in JIT code range

KEY_VALUES_STRING: 1

    Key  : Analysis.CPU.mSec
    Value: 67280

    Key  : Analysis.DebugAnalysisManager
    Value: Create

    Key  : Analysis.Elapsed.mSec
    Value: 75763

    Key  : Analysis.Init.CPU.mSec
    Value: 4436

    Key  : Analysis.Init.Elapsed.mSec
    Value: 9321

    Key  : Analysis.Memory.CommitPeak.Mb
    Value: 228

    Key  : CLR.BuiltBy
    Value: NET48REL1LAST_C

    Key  : CLR.Engine
    Value: CLR

    Key  : CLR.Version
    Value: 4.8.4515.0

    Key  : Timeline.OS.Boot.DeltaSec
    Value: 4888

    Key  : Timeline.Process.Start.DeltaSec
    Value: 117

    Key  : WER.OS.Branch
    Value: vb_release

    Key  : WER.OS.Timestamp
    Value: 2019-12-06T14:06:00Z

    Key  : WER.OS.Version
    Value: 10.0.19041.1

    Key  : WER.Process.Version
    Value: 6.0.0.209


FILE_IN_CAB:  CrashDump.dmp

NTGLOBALFLAG:  0

PROCESS_BAM_CURRENT_THROTTLED: 0

PROCESS_BAM_PREVIOUS_THROTTLED: 0

APPLICATION_VERIFIER_FLAGS:  0

EXCEPTION_RECORD:  (.exr -1)
ExceptionAddress: 00000000
   ExceptionCode: 80000003 (Break instruction exception)
  ExceptionFlags: 00000000
NumberParameters: 0

FAULTING_THREAD:  00005474

PROCESS_NAME:  NextGenEMR.exe

ERROR_CODE: (NTSTATUS) 0x80000003 - {EXCEPTION}  Breakpoint  A breakpoint has been reached.

EXCEPTION_CODE_STR:  80000003

IP_ON_HEAP:  477739d5
The fault address in not in any loaded module, please check your build's rebase
log at <releasedir>\bin\build_logs\timebuild\ntrebase.log for module which may
contain the address if it were loaded.

FRAME_ONE_INVALID: 1

STACK_TEXT:  
0019e0c8 09061cd1 OnCallBackMethod+0x2d1
0019e188 477739d5 unknown!unknown+0x0
0019e1ec 441b1553 unknown!unknown+0x0
0019e224 1c555afc igart18d+0x8e8c
0019e228 27195478 unknown!unknown+0x0
0019e240 27195478 unknown!unknown+0x0
0019e290 27195478 unknown!unknown+0x0
0019e2ac 1c5561d8 igart18d+0x9568


FAULTING_SOURCE_LINE:  D:\Core\PasteImage.cs

FAULTING_SOURCE_FILE:  D:\Core\PasteImage.cs

FAULTING_SOURCE_LINE_NUMBER:  724

SYMBOL_NAME:  OnCallBackMethod+2d1

MODULE_NAME: ImagingControl

IMAGE_NAME:  ImagingControl.dll

STACK_COMMAND:  .cxr 19d618 ; kb ; ** Pseudo Context ** Pseudo ** Value: f8b83f0 ** ; kb

FAILURE_BUCKET_ID:  BREAKPOINT_80000003_OnCallBackMethod

OS_VERSION:  10.0.19041.1

BUILDLAB_STR:  vb_release

OSPLATFORM_TYPE:  x86

OSNAME:  Windows 10

IMAGE_VERSION:  6.0.0.209

FAILURE_ID_HASH:  {bd0e81c1-c531-0b4a-964b-28450da23c4b}

Followup:     MachineOwner
---------


0:000> k
 # ChildEBP RetAddr      
00 0019d14c 75f82609     ntdll!NtWaitForSingleObject+0xc
01 0019d14c 729c1401     KERNELBASE!WaitForSingleObjectEx+0x99
02 0019d17c 729c145d     clr!CLREventWaitHelper2+0x33
03 0019d1cc 729c13aa     clr!CLREventWaitHelper+0x2a
04 0019d204 729c13cc     clr!CLREventBase::WaitEx+0x14b
05 0019d21c 72c9e065     clr!CLREventBase::Wait+0x1a
06 0019d288 72c9e17a     clr!Thread::WaitSuspendEventsHelper+0x8a
07 0019d29c 72c9c2aa     clr!Thread::WaitSuspendEvents+0x14
08 0019d2b4 72a89aae     clr!Thread::RareEnablePreemptiveGC+0x98
09 0019d2f8 72f642a5     clr!Thread::RareDisablePreemptiveGC+0x115
0a 0019d31c 72f69ccc     clr!GCHolderEEInterface<0,1,1>::~GCHolderEEInterface<0,1,1>+0x61
0b 0019d38c 72f6a75b     clr!DebuggerController::DispatchPatchOrSingleStep+0x1ef
0c 0019d3c0 72a7a625     clr!DebuggerController::DispatchNativeException+0x17c
0d 0019d3f0 72b4b82d     clr!Debugger::FirstChanceNativeException+0x69
0e 0019d430 72b4b91e     clr!CLRVectoredExceptionHandlerPhase2+0xa9
0f 0019d458 72b4d32c     clr!CLRVectoredExceptionHandler+0xac
10 0019d498 72b4d47a     clr!CPFH_FirstPassHandler+0x79
11 0019d4c4 77828a22     clr!COMPlusFrameHandler+0x15d
12 0019d4e8 778289f4     ntdll!ExecuteHandler2+0x26
13 0019d5b0 77814ee6     ntdll!ExecuteHandler+0x24
14 0019e170 09061cd1     ntdll!KiUserExceptionDispatcher+0x26
15 0019e170 477739d5     OnCallBackMethod+0x2d1 [PasteImage.cs @ 724] 
WARNING: Frame IP not in any known module. Following frames may be wrong.
16 0019e1e4 441b1553     0x477739d5
17 0019e21c 1c555afc     0x441b1553
18 27195478 27195478     igart18d!CPb_ART_done+0x8e8c
19 1c555afc 27195478     0x27195478
1a 0000000b 27195478     0x27195478
1b 1df00520 1c5561d8     0x27195478
1c 00000000 00000000     igart18d!CPb_ART_done+0x9568

0:000> dc 0x477739d5
477739d5  90909090 b9909090 46412a54 248baae8  ........T*AF...$
477739e5  c045892b ffc0458d c8fde830 45892b3f  +.E..E..0...?+.E
477739f5  b4558bb4 e80c4d8b 2b300d6f 000c7d83  ..U..M..o.0+.}..
47773a05  7d8b1974 b9c0330c 00000029 006aabf3  t..}.3..).....j.
47773a15  8bac4d8b 80e80c55 c72b300c 0004d845  .M..U....0+.E...
47773a25  90904000 d845c790 7fffffff 00e845c7  .@....E......E..
47773a35  c7000000 00fcec45 4f680000 eb47773a  ....E.....hO:wG.
47773a45  f8658d12 c25d5f5e 45c7000c 000000ec  ..e.^_]....E....

根因判定

该故障不属于堆泄漏,是典型的堆越界写导致的内存损坏。

  • 堆泄漏的核心特征是进程内存占用持续增长,最终触发内存不足错误,不会随机在回调返回时触发断点、执行流跳转异常,和当前故障表现完全不符
  • 转储中崩溃点0x477739d5属于CLR动态生成的反向PInvoke调用桩内存区域(JIT生成的可执行代码存放在堆上的专属段),该区域内存被非法覆盖:起始位置连续写入了大量0x90(NOP空指令)和非预期代码,是越界写篡改可执行内存的直接证据
  • 栈回溯出现大量无符号的未知栈帧、返回地址重复错乱,是栈内存、堆内存被越界写破坏的典型表现
  • 崩溃发生在C#回调返回、CLR切换GC模式的阶段,此时执行流从托管代码返回非托管桩时,直接跳到了被篡改的内存地址触发断点异常,属于原生层内存错误,完全绕过C#托管异常捕获机制,因此try/catch无法捕获

排查方案

  • 优先排查转储中出现的C++外部DLLigart18d.dll的回调相关逻辑:
    • 检查C++侧回调函数指针的调用约定、参数列表,必须和C#侧委托声明完全匹配,参数个数、类型长度、调用约定(__stdcall/__cdecl)不一致会直接导致栈平衡错误,破坏栈内存
    • 检查DLL内所有内存拷贝操作,重点排查无长度校验的memcpy、strcpy类接口,确认不存在拷贝长度超出目标缓冲区分配大小的情况
    • 检查DLL侧内存生命周期管理,确认不存在释放内存块后仍写入该内存地址的野指针问题
  • 检查C#侧回调委托生命周期:传给非托管层的委托必须被持有强引用,若委托被GC回收后,C++侧仍保存对应函数指针发起调用,会直接跳转至已被释放、重新分配的JIT桩内存,触发执行流异常
  • 开启堆监控工具定位越界点:
    • 使用gflags工具为目标进程开启全页堆(gflags /p /enable NextGenEMR.exe /full),复现崩溃时会直接在越界写操作的位置触发断点,不会等到内存被
相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 23:15:10