首页 > 其他分享 >记一次 .NET某实验室自动进样系统 崩溃分析

记一次 .NET某实验室自动进样系统 崩溃分析

时间:2024-08-27 12:37:01浏览次数:11  
标签:00000000 xxx 107 0000005e clean 自动进样 NET rbp 崩溃

一:背景

1. 讲故事

前些天有位朋友在微信上联系到我,说他们的程序在客户那边崩掉了,让我帮忙看下怎么回事,dump也拿到了,那就上手分析吧。

二:WinDbg 分析

1. 哪里的崩溃

既然是程序的崩溃,自然是有原因的,皮裤套棉裤,必定有缘故,不是皮裤太薄就是棉裤没毛,用 !analyze -v 观察下异常信息。


0:107> !analyze -v

CONTEXT:  (.ecxr)
rax=0000005e0dc7c4a0 rbx=0000005e0dc7c400 rcx=0000005e0dc7c4a0
rdx=0000000000000000 rsi=0000005e0dc7c3f0 rdi=0000005e0dc7c4a0
rip=00007ffb1ecfc223 rsp=0000005e0dc7c3c0 rbp=0000005e0dc7c4c0
 r8=00000000000004d0  r9=0000000000000000 r10=0000000000000000
r11=0000005e0dc7c4a0 r12=0000000000000000 r13=000002079d450220
r14=000002079b93aba0 r15=0000000000000000
iopl=0         nv up ei pl nz na pe nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000200
coreclr!EEPolicy::HandleFatalError+0x7f:
00007ffb`1ecfc223 488d442440      lea     rax,[rsp+40h]
Resetting default scope

EXCEPTION_RECORD:  (.exr -1)
ExceptionAddress: 00007ffb1ec6d70f (coreclr!ProcessCLRException+0x00000000000d9f7f)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000001
NumberParameters: 0

从卦中信息看这是一个经典的 访问违例,但崩溃在 EEPolicy::HandleFatalError 处就有点匪夷所思了,HandleFatalError 方法主要是用来在抛异常之前修整异常上下文的,这个方法固若金汤,一般不会出问题的,但不管怎么样,还是看下 rsp+40h 到底是什么东西。


0:107> dp rsp+40h L1
0000005e`0dc7c400  00000001`c0000005

上面的 c0000005 很显然是访问违例,看样子这里有点混乱,也不是第一崩溃现场,这里就不过多纠结了,那怎么去找真正的崩溃点呢?还有一个方法就是去找 RaiseException 或者 KiUserExceptionDispatch 返回点之前的有用函数,参考如下:


0:107> .ecxr
0:107> k
  *** Stack trace for last set context - .thread/.cxr resets it
 # Child-SP          RetAddr               Call Site
00 0000005e`0dc7c3c0 00007ffb`1ec6d72e     coreclr!EEPolicy::HandleFatalError+0x7f [D:\a\_work\1\s\src\coreclr\vm\eepolicy.cpp @ 776] 
01 0000005e`0dc7c9d0 00007ffb`5235292f     coreclr!ProcessCLRException+0xd9f9e [D:\a\_work\1\s\src\coreclr\vm\exceptionhandling.cpp @ 1036] 
02 0000005e`0dc7cc00 00007ffb`52302554     ntdll!RtlpExecuteHandlerForException+0xf
03 0000005e`0dc7cc30 00007ffb`5235143e     ntdll!RtlDispatchException+0x244
04 0000005e`0dc7d340 00000000`6c942893     ntdll!KiUserExceptionDispatch+0x2e
05 0000005e`0dc7daf0 00007ffa`c066ed7b     libxxx_manage!get_clean_xxx
06 0000005e`0dc7db70 00007ffa`c06b73a4     0x00007ffa`c066ed7b
...

从卦中看,程序崩溃在 libxxx_manage!get_clean_xxx 中,看样子是一个 C++ 写的动态链接库,这就有点无语了。。。

2. C++ 库为什么会崩

要想寻找答案,最好的办法就是观察 000000006c942893 处的汇编代码,参考如下:


0:107> ub 00000000`6c942893
libxxx_manage!get_clean_xxx:
00000000`6c942876 55              push    rbp
00000000`6c942877 53              push    rbx
00000000`6c942878 4883ec68        sub     rsp,68h
00000000`6c94287c 488dac2480000000 lea     rbp,[rsp+80h]
00000000`6c942884 48894d00        mov     qword ptr [rbp],rcx
00000000`6c942888 c745dc00000000  mov     dword ptr [rbp-24h],0
00000000`6c94288f 488b4500        mov     rax,qword ptr [rbp]

0:107> u 00000000`6c942893
00000000`6c942893 488b00          mov     rax,qword ptr [rax]

0:107> dp rbp L1
0000005e`0dc7c4c0  00000000`00000000

从上面的汇编代码来看,这是 get_clean_xxx 方法的序幕代码,问题出在 rbp 的内容为0上,但 rbp 又来自于 rcx,根据 x64调用协定,rcx 即方法的第一个参数,看样子是这个参数为 null 导致的,参考如下:


0:107> !address rcx

Usage:                  Stack
Base Address:           0000005e`0dc78000
End Address:            0000005e`0dc80000
Region Size:            00000000`00008000 (  32.000 kB)
State:                  00001000          MEM_COMMIT
Protect:                00000004          PAGE_READWRITE
Type:                   00020000          MEM_PRIVATE
Allocation Base:        0000005e`0db00000
Allocation Protect:     00000004          PAGE_READWRITE
More info:              ~107k

0:107> dp rcx L1
0000005e`0dc7c4a0  00000000`00000000

3. get_clean_xxx 参数为null吗

这个问题比较简单,继续用 !clrstack 观察下 Pinvoke 之上的 C# 代码。


0:107> !clrstack
OS Thread Id: 0x3508 (107)
        Child SP               IP Call Site
0000005E0DC7DBA0 00007ffac066ed7b [InlinedCallFrame: 0000005e0dc7dba0] xxx_LibPInvoke.xxx_clean_query(IntPtr)
0000005E0DC7DB70 00007ffac066ed7b ILStubClass.IL_STUB_PInvoke(IntPtr)
0000005E0DC7DC30 00007ffac06b73a4 xx+c__DisplayClass11_0.<xxxQueryClean>b__0(IntPtr)
...

接下来就是看下托管层的 C# 代码是如何写的,截图如下:

从图中可以清楚的看到,xxxChannel 传给C++ 的时候没有判断是否为null,导致崩溃的发生,那还有没有其他的佐证呢?其实也是有的,如果符号给力还可以使用 !clrstack -a 去找到 xxxChannel 传下去的值。


0:107> !clrstack -a
OS Thread Id: 0x3508 (107)
        Child SP               IP Call Site
0000005E0DC7DBA0 00007ffac066ed7b [InlinedCallFrame: 0000005e0dc7dba0] xxx_LibPInvoke.xxx_clean_query(IntPtr)
0000005E0DC7DB70 00007ffac066ed7b ILStubClass.IL_STUB_PInvoke(IntPtr)
    PARAMETERS:
        <no data>

0000005E0DC7DC30 00007ffac06b73a4 xxx+c__DisplayClass11_0.<xxxQueryClean>b__0(IntPtr)
    PARAMETERS:
        this (0x0000005E0DC7DC80) = 0x0000020a9d9ca8d8
        xxxChannel (0x0000005E0DC7DC88) = 0x0000000000000000
    LOCALS:
        0x0000005E0DC7DC6C = 0x0000000000000000
        0x0000005E0DC7DC68 = 0x0000000000000000

可以清楚的看到确实是 0,到这里就一切真相大白,对参数加一个判断即可,那这东西到底是谁的责任呢?我觉得双方都有问题吧。

  1. 写托管层的人有点飘。
  2. 写非托管层的人未作防御性编程,还是年轻太相信人了。

三:总结

这次生产事故彻底破坏了两个语言团队之间的相互合作的信任度,信任重建可就难了,不怕神一样的对手,就怕猪猪一样的队友,放在这里还是挺合适的,哈哈,开个小玩笑。

图片名称

标签:00000000,xxx,107,0000005e,clean,自动进样,NET,rbp,崩溃
From: https://www.cnblogs.com/huangxincheng/p/18382459

相关文章

  • 面试官:Leader崩溃Follower不够新怎么办?
    这是一道非常经典的Kafka问题,是关于Leader在“异常”情况下的选举问题。背景我们知道Kafka中的Partition(分区)是存储消息的最终介质,但Partition又有两种分类:LeaderPartition:主分区,负责数据写入和读取。FollowerPartition:副本分区,用于数据备份和主节点宕机之后的分......
  • oracle system信息统计,​Oracle的SYSTEM和SYSAUX表空间 转载:https://blog.csdn.net
    一般情况下,业务数据应该存放在单独的数据表空间,而不应该使用系统已存在的表空间,尤其不能将业务数据保存到SYSTEM和SYSAUX表空间中,所以,DBA需要着重关注SYSTEM和SYSAUX表空间的占用情况。Oracle服务器使用SYSTEM表空间管理整个数据库。这个表空间包含系统的数据字典和关于数据库的......
  • .NET 开源实时监控系统 - WatchDog
    前言在平时的开发中随着我们系统应用不断地迭代变的复杂,对应用的实时监控变得越来越重要。实时监控不仅可以帮助我们快速定位问题,还能在出现问题时及时采取措施,减少业务中断的时间。本文将介绍一个名为WatchDog的.NET开源实时应用监控系统,它可以帮助我们轻松实现对.NET应用的实......
  • DeviceNet主站转EtherCAT从站总线协议转换网关配置详情
    DeviceNet转EtherCAT如何实现有效连接与通信,这一问题常常让许多人感到困惑不已。现在,就来为大家专门解答这个疑问。远创智控YC-ECT-DNTM型设备有着极为出色的表现,能够成功地解决这个困扰众人的难题。接下来,会为大家详尽地介绍该设备的功能,像智能的网络管理功能以及强大的兼容性......
  • 《欧洲卡车模拟2》游戏启动时闪退提示缺少Core_ets2mp.dll文件怎么解决?欧卡2游戏崩溃
    在玩《欧洲卡车模拟2》时,游戏启动时出现闪退,并提示缺少Core_ets2mp.dll文件,这着实令人困扰。玩家可以尝试重新安装游戏、更新驱动程序,或者从可靠来源获取该文件并正确放置,以解决这一问题。本篇将为大家带来《欧洲卡车模拟2》游戏启动时闪退提示缺少Core_ets2mp.dll文件怎么解决......
  • 《魔兽世界》游戏崩溃弹窗“找不到gamede.dll文件”该怎么办?魔兽世界游戏闪退提示缺少
    在玩《魔兽世界》时,游戏崩溃并弹窗提示“找不到gamede.dll文件”,这十分令人头疼。玩家可以尝试重新安装游戏、检查文件完整性,或者在网上查找可靠的该文件资源进行补充,以此来解决这个棘手的问题。本篇将为大家带来《魔兽世界》游戏崩溃弹窗“找不到gamede.dll文件”该怎么办的内......
  • 使用try-convert将.NET Framework项目迁移到.NET Core
    try-convert 是一个命令行工具,它可以帮助开发者将.NETFramework项目迁移到.NETCore或.NET5/6/7(以及更高版本,取决于发布时的最新版本)。这是Microsoft官方提供的一个工具,旨在简化迁移过程,但请注意,它不会自动解决所有兼容性问题,因为它主要是帮助进行项目文件和配置文件......
  • C#/.NET/.NET Core技术前沿周刊 | 第 2 期(2024年8.19-8.25)
    前言C#/.NET/.NETCore技术前沿周刊,你的每周技术指南针!记录、追踪C#/.NET/.NETCore领域、生态的每周最新、最实用、最有价值的技术文章、社区动态、优质项目和学习资源等。让你时刻站在技术前沿,助力技术成长与视野拓宽。欢迎投稿,推荐或自荐优质文章/项目/学习资源等。每......
  • 【Kubernetes安装】WSL2+ubuntu22.04+K8s+minikube最新安装教程
    系列综述:......
  • Kubernetes API资源规范
    1.资源类型和资源对象1.1资源类型(ResourceTypes)1.1.1核心资源类型KubernetesAPIPrimitive用于描述在Kubernetes上运行应用程序的基本组件,即俗称的Kubernetes对象(Object)它们持久存储于APIServer上,用于描述集群的状态依据资源的主要功能作为分类标准,Kubernetes......