记一次 .NET某新能源检测系统 崩溃分析

这篇具有很好参考价值的文章主要介绍了记一次 .NET某新能源检测系统 崩溃分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一:背景

1. 讲故事

前几天有位朋友微信上找到我,说他的程序会偶发性崩溃,一直找不到原因,让我帮忙看一下怎么回事,对于这种崩溃类的程序,最好的办法就是丢dump过来看一下便知,话不多说,上windbg说话。

二:WinDbg 分析

1. 到底是哪里的崩溃

对于一个崩溃类的dump,寻找崩溃点非常重要,常用的命令就是 !analyze -v,输出如下:


0:006> !analyze -v
CONTEXT:  6fbdee65 -- (.cxr 0x6fbdee65)
eax=55d2ebff ebx=5e5f04c0 ecx=e8c434e8 edx=cf8bc35b esi=83008b05 edi=75880000
eip=3d83f98b esp=ce8b0774 ebp=5756ec8b iopl=0 vip     ov up ei pl nz na po nc
cs=4040  ss=0010  ds=81f8  es=00e1  fs=4e8b  gs=ffdb             efl=08758b00
4040:3d83f98b ??              ???
Resetting default scope

EXCEPTION_RECORD:  049bfbd0 -- (.exr 0x49bfbd0)
ExceptionAddress: 00000000
   ExceptionCode: 049bfbf8
  ExceptionFlags: 6f9b6c38
NumberParameters: 8752248
   Parameter[0]: 00000000
   Parameter[1]: 6f9c92a0
   Parameter[2]: 049bfbdc
   Parameter[3]: 00000008
   Parameter[4]: 00000000
   Parameter[5]: 049bfc34
   Parameter[6]: 6f9b6d0d
   Parameter[7]: a2cc713a
   Parameter[8]: 6f9b6c40
   Parameter[9]: 00000000
   Parameter[10]: 00844c80
   Parameter[11]: a2cc712a
   Parameter[12]: 00000000
   Parameter[13]: 049bfd2c
   Parameter[14]: 049bfc00

PROCESS_NAME:  xxxx.exe

ERROR_CODE: (NTSTATUS) 0x80000004 - {    }

EXCEPTION_CODE_STR:  80000004

FAULTING_THREAD:  ffffffff

从卦中的崩溃点来看,很奇怪,怎么 cs:eip 所处的地址没有机器码? 先不管了,看下异常状态 80000004,在微软的官方文档查一查:

记一次 .NET某新能源检测系统 崩溃分析

从图中信息看,应该是 F11 这种单步跟踪造成的,这就很奇葩了,分析了200+ 的dump,这种崩溃还是第一次遇到,无语,一下子陷入了迷茫。

2. 还有突破口吗

虽然 windbg 的自动化分析给出的信息很不尽如意,但没关系,根据强大的临场经验,我们直接切到异常前的状态,看看异常前的上下文有没有什么新的线索,删减后如下:


0:006> .ecxr
eax=00000000 ebx=049bec60 ecx=027e1374 edx=0b8024a8 esi=00000000 edi=049bebf8
eip=09fb48b1 esp=049beb98 ebp=049bebe0 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
xxx!xxx.Program.CurrentDomain_UnhandledException+0x29:
09fb48b1 cc              int     3
0:006> k
  *** Stack trace for last set context - .thread/.cxr resets it
 # ChildEBP RetAddr      
00 049bebe0 6f962546     xxx!xxx.Program.CurrentDomain_UnhandledException+0x29
...
11 049bf114 77a48962     clr!_except_handler4+0x29
12 049bf138 77a48934     ntdll!ExecuteHandler2+0x26
13 049bf200 77a34f86     ntdll!ExecuteHandler+0x24
14 049bf6f0 77a32b2c     ntdll!KiUserExceptionDispatcher+0x26
15 049bf6f0 76698d7a     ntdll!NtClose+0xc
16 049bf6f0 6f96287d     KERNELBASE!CloseHandle+0x4a
...
20 049bf970 78a1887b     clr!SafeHandle::Finalize+0x7a
21 049bf978 78a187e4     mscorlib_ni!System.Runtime.InteropServices.SafeHandle.Dispose+0x1b [f:\dd\ndp\clr\src\BCL\system\runtime\interopservices\safehandle.cs @ 263] 
22 049bf998 6f98df99     mscorlib_ni!System.Runtime.InteropServices.SafeHandle.Finalize+0x24 [f:\dd\ndp\clr\src\BCL\system\runtime\interopservices\safehandle.cs @ 199] 
23 049bf9ec 6f98e0a7     clr!FastCallFinalize+0x6d
24 049bfa10 6f98de5c     clr!MethodTable::CallFinalizer+0x150
25 049bfa78 6f98ded3     clr!CallFinalizer+0xa6
26 049bfa78 6f9c9263     clr!FinalizerThread::DoOneFinalization+0x132
27 049bfaa8 6f9c9343     clr!FinalizerThread::FinalizeAllObjects+0xa1
28 049bfad4 6f973b24     clr!FinalizerThread::FinalizerThreadWorker+0xbe
29 049bfaec 6f973b9b     clr!ManagedThreadBase_DispatchInner+0x71
2a 049bfb74 6f973c4b     clr!ManagedThreadBase_DispatchMiddle+0x8f
2b 049bfbd0 6f9b6c38     clr!ManagedThreadBase_DispatchOuter+0x6d
2c 049bfbf8 6f9b6d0d     clr!ManagedThreadBase::FinalizerBase+0x33
2d 049bfc34 6f98eb34     clr!FinalizerThread::FinalizerThreadStart+0xe2
2e 049bfcd0 76cdfcc9     clr!Thread::intermediateThreadProc+0x58
2f 049bfce0 77a27b1e     kernel32!BaseThreadInitThunk+0x19
30 049bfd3c 77a27aee     ntdll!__RtlUserThreadStart+0x2f
31 049bfd4c 00000000     ntdll!_RtlUserThreadStart+0x1b

从卦中的线程栈信息来看,逻辑还是非常清楚的,终结器线程析构一个C#的 SafeWaitHandle 对象时,在网关函数 ntdll!NtClose 中抛出了异常,这个函数再往下就是 内核层 了。

线程既然抛了异常,那 C# 层面有没有接到呢?可以用 !t 观察下。


0:006> !t
ThreadCount:      10
UnstartedThread:  0
BackgroundThread: 8
PendingThread:    0
DeadThread:       1
Hosted Runtime:   no
                                                                         Lock  
       ID OSID ThreadOBJ    State GC Mode     GC Alloc Context  Domain   Count Apt Exception
   0    1 4b9c 0085f088     a6028 Preemptive  0B7FF79C:00000000 00858c78 0     STA 
   6    2 5068 008a3708     ab228 Preemptive  0B8024B8:00000000 00858c78 0     MTA (Finalizer) System.Runtime.InteropServices.SEHException 0b800c88
  11    3 293c 0092c0a8   10a9228 Preemptive  00000000:00000000 00858c78 0     MTA (Threadpool Worker) 
  12    4 2eb0 0602ed48   8029228 Preemptive  00000000:00000000 00858c78 0     MTA (Threadpool Completion Port) 
XXXX    5    0 07de70a8   1039820 Preemptive  00000000:00000000 00858c78 0     Ukn (Threadpool Worker) 
  13    6 7e0c 0a7ada58   102a228 Preemptive  00000000:00000000 00858c78 0     MTA (Threadpool Worker) 
  14    7 7c60 0a773950   1029228 Preemptive  00000000:00000000 00858c78 0     MTA (Threadpool Worker) 
  15    8 5c24 0a775f68   10a9228 Preemptive  0B7EB8CC:00000000 00858c78 0     MTA (Threadpool Worker) 
  16    9 698c 008d5b40   1029228 Preemptive  00000000:00000000 00858c78 0     MTA (Threadpool Worker) 
  17   10 7de4 008dea10   1029228 Preemptive  0B7ECE80:00000000 00858c78 0     MTA (Threadpool Worker) 
0:006> !PrintException /d 0b800c88
Exception object: 0b800c88
Exception type:   System.Runtime.InteropServices.SEHException
Message:          外部组件发生异常。
InnerException:   <none>
StackTrace (generated):
    SP       IP       Function
    00000000 00000000 mscorlib_ni!Microsoft.Win32.Win32Native.CloseHandle(IntPtr)+0x1
    049BF760 78ADF5FE mscorlib_ni!Microsoft.Win32.SafeHandles.SafeWaitHandle.ReleaseHandle()+0xe
    00000000 00000001 mscorlib_ni!System.Runtime.InteropServices.SafeHandle.InternalFinalize()+0xffffffff90656c91
    049BF978 78A1887B mscorlib_ni!System.Runtime.InteropServices.SafeHandle.Dispose(Boolean)+0x1b
    049BF980 78A187E4 mscorlib_ni!System.Runtime.InteropServices.SafeHandle.Finalize()+0x24

StackTraceString: <none>
HResult: 80004005

从卦中信息看,果然是在析构 SafeHandle.Finalize 时异常了,但这个异常信息 Message:外部组件发生异常 对我们来说一点作用都没有,到这里貌似又进行不下去了。

3. 从 handle 上突破

托管层没法挖了,那就继续挖非托管层,也就是异常前的最后一个函数 ntdll!NtClose,这个函数其实没什么特别的,也就是释放句柄,这个函数一般来说固若金汤,不会有异常的,不管怎么说,先把句柄值找出来看看,签名如下:


NTSTATUS NTAPI NtClose(
  HANDLE Handle
);

如何提取出 handle 呢?非常简单,用 kb 即可。


0:006> kb 
  *** Stack trace for last set context - .thread/.cxr resets it
 # ChildEBP RetAddr      Args to Child    
...
13 049bf200 77a34f86     049bf218 049bf268 049bf218 ntdll!ExecuteHandler+0x24
14 049bf6f0 77a32b2c     00000664 049bf730 008a3708 ntdll!KiUserExceptionDispatcher+0x26
15 049bf6f0 76698d7a     00000664 049bf6fc 049bf72c ntdll!NtClose+0xc
16 049bf6f0 6f96287d     00000664 049bf730 008a3708 KERNELBASE!CloseHandle+0x4a
...

0:006> !handle 00000664 f
Handle 00000664
  Type         	<Error retrieving type>
unable to query object information
unable to query object information
  No object specific information available

我去,卦中显示这个 handle=664 句柄值居然不在进程中,难怪调用 ntdll!NtClose 会报错,接下来的问题就是这个 handle 到底怎么了?要找到这个答案,需要从线程栈上把 _EXCEPTION_RECORD 结构体给提取出来,它的内部记录了 ExceptionCode ,而且刚好线程栈上的 ntdll!ExecuteHandler 方法的第一个参数就是这个结构体。


0:006> dt _EXCEPTION_RECORD 049bf218
VCRUNTIME140_CLR0400!_EXCEPTION_RECORD
   +0x000 ExceptionCode    : 0xc0000008
   +0x004 ExceptionFlags   : 0
   +0x008 ExceptionRecord  : (null) 
   +0x00c ExceptionAddress : 0x74a70daa Void
   +0x010 NumberParameters : 0
   +0x014 ExceptionInformation : [15] 0

接下来就是找下 ExceptionCode=0xc0000008 代表什么意思,这个简单,网上搜一下便知,截图如下:

记一次 .NET某新能源检测系统 崩溃分析

到这里就很好理解了,然来是在释放一个已经释放的句柄,这个肯定会报错的,据朋友所说,他们的程序是 C# 和 C++ 混合编程的,那大概率就是 handle=664 被 C++ 给提前释放了。

有些朋友肯定要问了,那我怎么找到释放这个 handle 的代码呢?要寻找这个答案,需要通过 perfview 对 handle 进行全程监控,参见:https://www.cnblogs.com/huangxincheng/p/17559370.html

三:总结

这个崩溃还是挺有意思的,需要你对 Windows 层面的知识有一定的了解,否则很难找出前因后果,所以请善待做大工控的朋友。文章来源地址https://www.toymoban.com/news/detail-711548.html

记一次 .NET某新能源检测系统 崩溃分析

到了这里,关于记一次 .NET某新能源检测系统 崩溃分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 记一次 .NET 某工控电池检测系统 卡死分析

    前几天有位朋友找到我,说他的窗体程序有卡死现象,让我帮忙看下怎么回事,解决这种问题就需要在卡死的时候抓一个dump下来,拿到dump之后就可以分析了。 窗体程序的卡死,需要观察主线程此时正在做什么,可以用 !clrstack 命令观察。 从卦中的线程栈数据来看,貌似是卡

    2024年02月05日
    浏览(42)
  • 记一次 .NET某管理局检测系统 内存暴涨分析

    前些天有位朋友微信找到我,说他们的WPF程序有内存泄漏的情况,让我帮忙看下怎么回事?并且dump也抓到了,网上关于程序内存泄漏,内存暴涨的文章不计其数,看样子这个dump不是很好分析,不管怎么说,上 windbg 说话。 在 .NET调试训练营 中我一直强调要相信数据,不要相

    2024年04月08日
    浏览(93)
  • 开发新能源的好处

    风能无论是总 装机容量 还是新增装机容量,全球都保持着较快的发展速度,风能将迎来发展高峰。风电上网电价高于火电,期待价格理顺促进发展。 生物质能有望在农业资源丰富的热带和亚热带普及,主要问题是降低 制造成本 ,生物乙醇、生物柴油以及 二甲醚 燃料应用值

    2024年02月11日
    浏览(44)
  • 【笔记】关于新能源

    新能源发电的间歇性和不确定性主要指: 间歇性(Intermittency) : 新能源如太阳能和风能等,其发电量受到自然条件的直接影响。例如,太阳能发电依赖于日照强度,而风能发电则取决于风速大小。这些自然资源在时间和空间上都有显著的不连续和变化特性。白天和黑夜、季

    2024年01月19日
    浏览(37)
  • 新能源汽车电控系统

    新能源汽车电控系统主要分为:三电系统电控系统、高压系统电控系统、低压系统电控系统 包括整车控制器、电池管理系统、驱动电机控制器等。 整车控制器VCU 整车控制器作为电动汽车中央控制单元,是整个控制系统的核心,也是各个子系统的调控中心。 VCU 集成驾驶员意

    2024年02月12日
    浏览(43)
  • 新能源汽车的发展

    目录 1.什么是新能源 2.什么是新能源汽车 3.新能源汽车的优点 4.新能源汽车的危害 5.新能源汽车未来的发展         新能源是指与传统能源(如化石燃料)相比,更具可再生性、清洁性和低碳排放的能源形式。它主要通过利用自然资源和可再生能源来满足人类的能源需求

    2024年02月15日
    浏览(44)
  • 谈谈新能源技术

    目录 1.什么是新能源 2.新能源的发展历程 3.新能源的优势         新能源是指利用自然界可再生资源、无害的高效能资源或者核能等来替代传统能源的能源形式。与传统化石燃料相比,新能源具有更高的可持续性、更低的环境影响和更长久的供应。以下是一些常见的新能

    2024年02月14日
    浏览(28)
  • 思格新能源面试(部分)

    面试官聊到他们是做储能的,是从华为数字能源独立出来的。他们主要缺算法的人。他们调用了ChatGPT的接口,但一是比较慢,二是回答质量不太满意。 你了解一些大数据技术吗,你们公司用到哪些? 有没有一些实时的流式计算的场景?Answer by newBing : 大数据技术中的实时流式

    2024年02月15日
    浏览(40)
  • 新能源科学与工程专业概述

    英文名称:New Energy Science and Engineering 新能源科学与工程 该专业为2011年新增专业,主要学习新能源的种类和特点、利用的方式和方法、应用的现状和未来的发展趋势。具体内容涉及太阳能、风能、生物质能、核电能、化石能源等等。 近年来我国经济持续高速增长,传统能源

    2024年02月03日
    浏览(36)
  • 紧跟国家“新能源+”模式!涂鸦智慧能源方案助力夏季用电节能提效

    “今天的你是几分熟?” 今年夏天,高温来得比往年更早,五六月份就提前开启了滚滚热浪模式,京津冀和山东等地最高气温也一度突破了历史极值。在提前到来的高温“烤”验下,全社会供电能力面临着极大挑战。 中国电力网预计,2023 年全国用电量将同比增长 6% 至 8%。

    2024年02月16日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包