记一次 腾讯会议 的意外崩溃分析

一次,腾讯,会议,意外,崩溃,分析 · 浏览次数 : 4394

小编点评

**分析 dump 信息** **错误码:18** **描述:该错误码代表在处理文件抛出异常时抛出的崩溃错误,具体异常码为 0x12** **建议:** * 仔细分析错误日志,找到导致崩溃的具体文件和操作。 * 尝试修复错误文件,如果无法修复,可以尝试删除或修复相关文件。 * 更新软件版本,确保所有软件都支持最新版本。 * 尝试解决相关问题,例如文件锁定或权限错误。 **其他信息:** * dump 信息包含一个异常列表,其中包含 0 个异常。 * 异常列表中包含异常类型和异常值。 * 异常类型为 `There are no more files. 错误`。 * 异常值是 `0x12`。

正文

一:背景

1. 讲故事

前段时间在用 腾讯会议 直播的时候,居然意外崩溃了,还好不是在训练营上课,不然又得重录了,崩完之后发现 腾讯会议 的 bugreport 组件会自动生成一个 minidump,截图如下:

作为一个.NET高级调试的技术博主,非 .NET 的程序也得要研究研究哈😄😄😄,有了这个好奇心,也有了这个 dump,接下来用 windbg 看一看吧。

二:WinDbg 分析

1. 为什么会崩溃

在 Windows 平台上不管是硬件异常还是软件异常 操作系统都会帮忙构造一个 EXCEPTION_POINTERS 结构体,这里面就包含了程序的崩溃点,错误码等各种非常有价值的信息,要想洞察这个结构体,要么在栈上提取,要么用 !analyze -v 自动化提取,这里采用后者。


0:000> !analyze -v

CONTEXT:  (.ecxr)
eax=008fdfe4 ebx=00000001 ecx=00000000 edx=2d692620 esi=3c4e1818 edi=3207f464
eip=1c5b34aa esp=008fe034 ebp=008fe094 iopl=0         nv up ei pl nz ac pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010216
meeting_dashboard_module+0x34aa:
1c5b34aa 8b01            mov     eax,dword ptr [ecx]  ds:002b:00000000=????????
Resetting default scope

EXCEPTION_RECORD:  (.exr -1)
ExceptionAddress: 1c5b34aa (meeting_dashboard_module+0x000034aa)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000000
   Parameter[1]: 00000000
Attempt to read from address 00000000

PROCESS_NAME:  wemeetapp.exe

READ_ADDRESS:  00000000 

ERROR_CODE: (NTSTATUS) 0xc0000005 - 0x%p            0x%p                    %s

EXCEPTION_CODE_STR:  c0000005

EXCEPTION_PARAMETER1:  00000000

EXCEPTION_PARAMETER2:  00000000

STACK_TEXT:  
WARNING: Stack unwind information not available. Following frames may be wrong.
008fe094 7ad808f4     008fe320 00000000 ec0d8f9b meeting_dashboard_module+0x34aa
008fe214 7ad80617     008fe2f0 ec0d89ef 4ee246d8 desktop_common+0x108f4
008fe460 7ad7f4d7     776f6873 008fe400 79641fe1 desktop_common+0x10617
008fe5ec 7ad7ae62     008fe9d0 008fe76c 79bce43a desktop_common+0xf4d7
008fe5f8 79bce43a     008fe6b8 a0f1fbb4 326aed58 desktop_common+0xae62
008fe76c 7ad7de66     00000000 008fe9d0 ec0d8a63 wemeet_framework+0x2e43a
008fe7ec 7ad7deed     00000000 008fe9d0 008fe808 desktop_common+0xde66
008fe7fc 7ad7ae62     008fe9d0 008fe97c 79bce43a desktop_common+0xdee
...

从上面的 ExceptionCode: c0000005 来看,这是一个经典的访问违例,从崩溃汇编的 mov eax,dword ptr [ecx] ds:002b:00000000=???????? 来看,当前的 ecx 中存放的是 0 ,从 0 上取内容自然就是访问违例。

2. 为什么会访问违例

要想知道访问违例的原因,就需要分析一下附近的汇编代码,用 .ecxr ; k 切到异常前的崩溃上下文。


0:000> .ecxr ; k
eax=008fdfe4 ebx=00000001 ecx=00000000 edx=2d692620 esi=3c4e1818 edi=3207f464
eip=1c5b34aa esp=008fe034 ebp=008fe094 iopl=0         nv up ei pl nz ac pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010216
meeting_dashboard_module+0x34aa:
1c5b34aa 8b01            mov     eax,dword ptr [ecx]  ds:002b:00000000=????????
  *** Stack trace for last set context - .thread/.cxr resets it
 # ChildEBP RetAddr      
WARNING: Stack unwind information not available. Following frames may be wrong.
00 008fe094 7ad808f4     meeting_dashboard_module+0x34aa
01 008fe214 7ad80617     desktop_common+0x108f4
02 008fe460 7ad7f4d7     desktop_common+0x10617
03 008fe5ec 7ad7ae62     desktop_common+0xf4d7
04 008fe5f8 79bce43a     desktop_common+0xae62
05 008fe76c 7ad7de66     wemeet_framework+0x2e43a
06 008fe7ec 7ad7deed     desktop_common+0xde66
07 008fe7fc 7ad7ae62     desktop_common+0xdeed
08 008fe808 79bce43a     desktop_common+0xae62
09 008fe97c 79bc784c     wemeet_framework+0x2e43a
0a 008fe98c 79bc821f     wemeet_framework+0x2784c
0b 008fe9a0 79bdac53     wemeet_framework+0x2821f
0c 008fea1c 79bdb791     wemeet_framework+0x3ac53
...

由于没有这些 dll 的符号,windbg 为了定义代码行数,就只能用 module + 0xxxxx 作为偏移来定位。

现在我们知道 ecx=0,那为什么会是 0 呢?接下来用 ub 观察下汇编代码逻辑,截图如下:


0:000> ub 1c5b34aa L20
meeting_dashboard_module+0x3449:
1c5b3449 00c6            add     dh,al
1c5b344b 45              inc     ebp
1c5b344c b000            mov     al,0
1c5b344e e8cde2ffff      call    meeting_dashboard_module+0x1720 (1c5b1720)
1c5b3453 8d45b0          lea     eax,[ebp-50h]
1c5b3456 c645fc04        mov     byte ptr [ebp-4],4
1c5b345a 50              push    eax
1c5b345b 8bce            mov     ecx,esi
1c5b345d ff15a8cb611c    call    dword ptr [meeting_dashboard_module+0x6cba8 (1c61cba8)]
1c5b3463 8d4db0          lea     ecx,[ebp-50h]
1c5b3466 8945c8          mov     dword ptr [ebp-38h],eax
1c5b3469 c645fc00        mov     byte ptr [ebp-4],0
1c5b346d e8feebffff      call    meeting_dashboard_module+0x2070 (1c5b2070)
1c5b3472 51              push    ecx
1c5b3473 8b4d0c          mov     ecx,dword ptr [ebp+0Ch]
1c5b3476 8bd4            mov     edx,esp
1c5b3478 c7450c00000000  mov     dword ptr [ebp+0Ch],0
1c5b347f 890a            mov     dword ptr [edx],ecx
1c5b3481 8bcf            mov     ecx,edi
1c5b3483 e8d8010000      call    meeting_dashboard_module+0x3660 (1c5b3660)
1c5b3488 837dc801        cmp     dword ptr [ebp-38h],1
1c5b348c 8b4f08          mov     ecx,dword ptr [edi+8]
1c5b348f 8b01            mov     eax,dword ptr [ecx]
1c5b3491 7509            jne     meeting_dashboard_module+0x349c (1c5b349c)
1c5b3493 6a01            push    1
1c5b3495 6a01            push    1
1c5b3497 ff507c          call    dword ptr [eax+7Ch]
1c5b349a eb2b            jmp     meeting_dashboard_module+0x34c7 (1c5b34c7)
1c5b349c ff5048          call    dword ptr [eax+48h]
1c5b349f 8bc8            mov     ecx,eax
1c5b34a1 ff15ccc6611c    call    dword ptr [meeting_dashboard_module+0x6c6cc (1c61c6cc)]
1c5b34a7 8b4f08          mov     ecx,dword ptr [edi+8]
1c5b34aa 8b01            mov     eax,dword ptr [ecx]
...

从汇编代码看,当前的 ecx 是来自于地址 edi+8,edi 的值有可能会在 meeting_dashboard_module+0x6c6cc (1c61c6cc) 方法中被修改,我们一并观察下。


0:000> dp @edi+8 L2
3207f46c  ???????? ????????

0:000> u 1c61c6cc
meeting_dashboard_module+0x6c6cc:
1c61c6cc ??              ???
                ^ Memory access error in 'u 1c61c6cc'

我去,都是 ???,这表示当前的数据和机器指令都没有纳入到 dump 中,这也就是为什么 dump 小的原因。

到这里好像就没法继续分析了,天要绝人之路吗?

3. 还有希望吗

虽然被当头一棒,但总得要挣扎一下吧,突破口也只能是汇编代码了,通过仔细观察,由于倒数第五行是一个 jmp 指令,所以语句指令 1c5b349c 肯定是从别的地方飞跃过来的,翻译成 C 代码就是一个 if else 的判断,截图如下:

既然走到了 else 的逻辑,那必然 ebp-38h 上的值肯定不是 1,那到底是多少呢?可以来查一查。

0:000> dp @ebp-38h L1
008fe05c  00000000

@ebp-38h 是谁给的呢?继续观察汇编代码,发现是 meeting_dashboard_module+0x6cba8 函数的返回值 eax 给的 ,从汇编逻辑看, 0 是一种异常状态。

4. 为什么会返回 0

返回 0 也暗示了代码在哪里报了一些错,可以用 GetLastError() 来获取可能调用 win32api 出错时设置的错误码,用 !teb 观察里面的 LastErrorValue 值。


0:000> !teb
TEB at 0078a000
    ExceptionList:        008fcf94
    StackBase:            00900000
    StackLimit:           008ee000
    SubSystemTib:         00000000
    FiberData:            00001e00
    ArbitraryUserPointer: 00000000
    Self:                 0078a000
    EnvironmentPointer:   00000000
    ClientId:             00003ccc . 00004484
    Real ClientId:        00000000 . 00000000
    RpcHandle:            00000000
    Tls Storage:          40a94180
    PEB Address:          00787000
    LastErrorValue:       18
    LastStatusValue:      0
    Count Owned Locks:    0
    HardErrorMode:        0

这里的 18 是一个十进制,十六进制就是 0x12 ,那这个错误码代表什么意思呢? !error 已经不支持了,只能上 msdn 上找答案,截图如下:

汇总一下:在腾讯会议录制期间,可能是处理什么文件抛了一个 There are no more files. 错误,在错误处理的后续逻辑中抛了崩溃。

有了这个信息之后,可以到外网搜一下 (https://windowsreport.com/there-are-no-more-files),常见的解决办法如下:

  • Solution 1 — Remove folder lock
  • Solution 2 – Repair your registry
  • Solution 3 — Run a full system scan
  • Solution 4 — Update your OS
  • Solution 5 — Remove recently installed software
  • Solution 6 — Uninstall Comodo Cleaner/ ASUS security data manager
  • Solution 7 — Boot into Safe Mode

具体是什么原因,由于缺少符号再深入分析下去得要花一些时间了,这里就到此为止吧。

三:总结

崩溃的 dump 已经第一时间提交上去了,相信腾讯会议的研发团队能够很快解决,作为一个付费会员,真心希望在下次录制的时候不要再崩了。

图片名称

与记一次 腾讯会议 的意外崩溃分析相似的内容:

记一次 腾讯会议 的意外崩溃分析

一:背景 1. 讲故事 前段时间在用 腾讯会议 直播的时候,居然意外崩溃了,还好不是在训练营上课,不然又得重录了,崩完之后发现 腾讯会议 的 bugreport 组件会自动生成一个 minidump,截图如下: 作为一个.NET高级调试的技术博主,非 .NET 的程序也得要研究研究哈😄😄😄,有

记一次 CDN 流量被盗刷经历

先说损失,被刷了 70 多RMB,还好止损相对即时了,亏得不算多,PCDN 真可恶啊。 600多G流量,100多万次请求。 怎么发现的 先是看到鱼皮大佬发了一篇推文突发,众多网站流量被盗刷!我特么也中招了。 抱着看热闹的心情点开阅读了。。。心想,看看自己的中招没,结果就真中招了 。 被盗刷资源分

记一次 .NET某上位视觉程序 离奇崩溃分析

一:背景 1. 讲故事 前段时间有位朋友找到我,说他们有一个崩溃的dump让我帮忙看下怎么回事,确实有太多的人在网上找各种故障分析最后联系到了我,还好我一直都是免费分析,不收取任何费用,造福社区。 话不多说,既然有 dump 来了,那就上 windbg 说话吧。 二:WinDbg 分析 1. 为什么

记一次 .NET某酒业业务系统 崩溃分析

一:背景 1. 讲故事 前些天有位朋友找到我,说他的程序每次关闭时就会自动崩溃,一直找不到原因让我帮忙看一下怎么回事,这位朋友应该是第二次找我了,分析了下 dump 还是挺经典的,拿出来给大家分享一下吧。 二:WinDbg 分析 1. 为什么会崩溃 找崩溃原因比较简单,用 !analyze -v 命

记一次aspnetcore发布部署流程初次使用k8s

主题: aspnetcorewebapi项目,提交到gitlab,通过jenkins(gitlab的ci/cd)编译、发布、推送到k8s。 关于gitlab、jenkins、k8s安装,都是使用docker启动服务。 首先新建一个项目,为了方便浏览就把swaggerr非开发环境不展示去掉 下面就是需

记一次 .NET某网络边缘计算系统 卡死分析

一:背景 1. 讲故事 早就听说过有什么 网络边缘计算,这次还真给遇到了,有点意思,问了下 chatgpt 这是干嘛的 ? 网络边缘计算是一种计算模型,它将计算能力和数据存储位置从传统的集中式数据中心向网络边缘的用户设备、传感器和其他物联网设备移动。这种模型的目的是在接近数据生成源头的地方提供更快速

记一次RocketMQ消费非顺序消息引起的线上事故

应用场景 C端用户提交工单、工单创建完成之后、会发布一条工单创建完成的消息事件(异步消息)、MQ消费者收到消息之后、会通知各处理器处理该消息、各处理器处理完后都会发布一条将该工单写入搜索引擎的消息、最终该工单出现在搜索引擎、被工单处理人检索和处理。 事故异常体现 1、异常体现 从工单的流转记录发现、

记一次难忘的json反序列化问题排查经历

前言 最近我在做知识星球中的商品秒杀系统,昨天遇到了一个诡异的json反序列化问题,感觉挺有意思的,现在拿出来跟大家一起分享一下,希望对你会有所帮助。 案发现场 我最近在做知识星球中的商品秒杀系统,写了一个filter,获取用户请求的header中获取JWT的token信息。 然后根据token信息

记一次 .NET某机械臂上位系统 卡死分析

一:背景 1. 讲故事 前些天有位朋友找到我,说他们的程序会偶发性的卡死一段时间,然后又好了,让我帮忙看下怎么回事?窗体类的程序解决起来相对来说比较简单,让朋友用procdump自动抓一个卡死时的dump,拿到dump之后,上 windbg 说话。 二:WinDbg 分析 1. 主线程在做什么 要想

记一次 .NET某工厂报警监控设置 崩溃分析

一:背景 1. 讲故事 前些天有位朋友在微信上丢了一个崩溃的dump给我,让我帮忙看下为什么出现了崩溃,在 Windows 的事件查看器上显示的是经典的 访问违例 ,即 c0000005 错误码,不管怎么说有dump就可以上windbg开干了。 二:WinDbg 分析 1. 程序为谁崩溃了 在 Wi