记一次 .NET某施工建模软件 卡死分析

news2024/10/6 2:25:12

一:背景

1. 讲故事

前几天有位朋友在微信上找到我,说他的软件卡死了,分析了下也不知道是咋回事,让我帮忙看一下,很多朋友都知道,我分析dump是免费的,当然也不是所有的dump我都能搞定,也只能尽自己最大能力帮助别人缩小问题范围吧,既然dump有了,接下来就开启分析之路。

二:WinDbg分析

1. 为什么会卡死

不同类型的程序卡死的解决思路是不一样的,朋友也说了是窗体程序,那就重点观察下主线程吧,使用 k 命令即可。


0:000> k 25
 # Child-SP          RetAddr               Call Site
00 00000000`007fc8d8 00007ffd`87439b13     ntdll!NtWaitForAlertByThreadId+0x14
01 00000000`007fc8e0 00007ffd`87439a06     ntdll!RtlpWaitOnAddressWithTimeout+0x43
02 00000000`007fc910 00007ffd`8743987d     ntdll!RtlpWaitOnAddress+0xae
03 00000000`007fc980 00007ffd`87435fdc     ntdll!RtlpWaitOnCriticalSection+0xd9
04 00000000`007fc9f0 00007ffd`87435ef0     ntdll!RtlpEnterCriticalSectionContended+0xdc
05 00000000`007fca20 00007ffd`536839ea     ntdll!RtlEnterCriticalSection+0x40
06 00000000`007fca50 00007ffd`5368470a     AcLayers!NS_VirtualRegistry::CRegLock::CRegLock+0x1a
07 00000000`007fca90 00007ffd`536726d2     AcLayers!NS_VirtualRegistry::APIHook_RegOpenKeyExW+0x2a
08 00000000`007fcb10 00007ffd`778e550b     AcLayers!NS_WRPMitigation::APIHook_RegOpenKeyExW+0x42
09 00000000`007fcb60 00007ffd`778e5437     xxx!GetCodePageForFont+0xa7
0a 00000000`007fcc90 00007ffd`778e5296     xxx!CToolTipsMgr::NewFont+0x113
0b 00000000`007fcda0 00007ffd`778e18f9     xxx!CToolTipsMgr::LoadTheme+0xb2
0c 00000000`007fcdd0 00007ffd`84b9ca66     xxx!CToolTipsMgr::s_ToolTipsWndProc+0x1b9
0d 00000000`007fce10 00007ffd`84b9c34b     user32!UserCallWinProcCheckWow+0x266
0e 00000000`007fcf90 00007ffd`4f36b1cc     user32!CallWindowProcW+0x8b
0f 00000000`007fcfe0 00007ffd`4f39ccac     System_Windows_Forms_ni!System.Windows.Forms.NativeWindow.DefWndProc+0x9c
10 00000000`007fd090 00007ffd`4f39cc05     System_Windows_Forms_ni!System.Windows.Forms.ToolTip.WndProc+0x9c
11 00000000`007fd260 00007ffd`4f36a3a3     System_Windows_Forms_ni!System.Windows.Forms.ToolTip.ToolTipNativeWindow.WndProc+0x15
12 00000000`007fd290 00007ffd`4f9e1161     System_Windows_Forms_ni!System.Windows.Forms.NativeWindow.Callback+0xc3
13 00000000`007fd330 00007ffd`52c8222e     System_Windows_Forms_ni+0x8d1161
14 00000000`007fd3a0 00007ffd`84b9ca66     clr!UMThunkStub+0x6e
15 00000000`007fd430 00007ffd`84b9c78c     user32!UserCallWinProcCheckWow+0x266
16 00000000`007fd5b0 00007ffd`84bb3b32     user32!DispatchClientMessage+0x9c
17 00000000`007fd610 00007ffd`874c22c4     user32!__fnINLPCREATESTRUCT+0xa2
18 00000000`007fd670 00007ffd`836a1f24     ntdll!KiUserCallbackDispatcherContinue
19 00000000`007fd7e8 00007ffd`84ba15df     win32u!NtUserCreateWindowEx+0x14
1a 00000000`007fd7f0 00007ffd`84ba11d4     user32!VerNtUserCreateWindowEx+0x20f
1b 00000000`007fdb80 00007ffd`84ba1012     user32!CreateWindowInternal+0x1b4
1c 00000000`007fdce0 00007ffd`4f3e8098     user32!CreateWindowExW+0x82
1d 00000000`007fdd70 00007ffd`4f3696f0     System_Windows_Forms_ni+0x2d8098
...

从卦象看,很明显主线程卡在 NtWaitForAlertByThreadId 上,这是有问题的,接下来我们仔细解读下线程栈。

  • DispatchClientMessage

这个方法表示当前从 queue 中拿到了别的线程通过 Invoke 送过来的信息,正在处理中。

  • LoadTheme

这个方法表示正在用主线程更新窗体样式

  • APIHook_RegOpenKeyExW

首先说一下 AcLayers.dll,专业名词叫 垫片,详情可以看一下《软件调试》,它主要用来处理一些系统级兼容性的问题,然后可以看到它在查询注册表时有一个lock操作。

在非托管代码中,lock 一般都用 临界区(CriticalSection) 实现,那到底它等待的临界区被谁持有着呢?

2. 谁持有着临界区锁

要想获取锁的持有信息,可以使用 !cs -l 或者 !locks,但这里要提醒一下,在真实的dump分析过程中,有时候不准,所以更好的办法就是从线程栈上提取,那怎么提取呢? 其实就是寻找 ntdll!RtlEnterCriticalSection 方法的第一个参数即可,方法签名如下:


VOID RtlEnterCriticalSection(
  PRTL_CRITICAL_SECTION CriticalSection
);

接下来反汇编下 00007ffd536839ea 处的代码,看看 rcx 寄存器是怎么传下来的。


0:000> ub 00007ffd`536839ea
AcLayers!NS_VirtualRegistry::OPENKEY::AddEnumEntries<NS_VirtualRegistry::VIRTUALVAL>+0x11a:
00007ffd`536839ce cc              int     3
00007ffd`536839cf cc              int     3
AcLayers!NS_VirtualRegistry::CRegLock::CRegLock:
00007ffd`536839d0 48895c2408      mov     qword ptr [rsp+8],rbx
00007ffd`536839d5 57              push    rdi
00007ffd`536839d6 4883ec30        sub     rsp,30h
00007ffd`536839da 488bf9          mov     rdi,rcx
00007ffd`536839dd 488d0d4c7f0300  lea     rcx,[AcLayers!NS_VirtualRegistry::csRegCriticalSection (00007ffd`536bb930)]
00007ffd`536839e4 ff15ae660100    call    qword ptr [AcLayers!_imp_EnterCriticalSection (00007ffd`5369a098)]

从卦象上看,很吉利,这个 rcx 原来是一个全局变量 AcLayers!NS_VirtualRegistry::csRegCriticalSection, 接下来用 !cs 观察下到底被谁持有着。


0:000> !cs AcLayers!NS_VirtualRegistry::csRegCriticalSection
-----------------------------------------
Critical section   = 0x00007ffd536bb930 (AcLayers!NS_VirtualRegistry::csRegCriticalSection+0x0)
DebugInfo          = 0x000000001c4e58e0
LOCKED
LockCount          = 0x2
WaiterWoken        = No
OwningThread       = 0x0000000000001d20
RecursionCount     = 0x1
LockSemaphore      = 0xFFFFFFFF
SpinCount          = 0x00000000020007ce

这又是一副吉卦,可以看到当前持有线程是 1d20,那这个线程正在做什么呢?

3. 1d20 线程为什么持锁不释放

案情往前推进了一步,我们切过去观察下这个线程栈。


0:000> ~~[1d20]s
ntdll!NtDelayExecution+0x14:
00007ffd`874bec14 c3              ret
0:028> kL
 # Child-SP          RetAddr               Call Site
00 00000000`33ccd948 00007ffd`83955381     ntdll!NtDelayExecution+0x14
01 00000000`33ccd950 00007ffd`6d4a2361     KERNELBASE!SleepEx+0xa1
02 00000000`33ccd9f0 00007ffd`8520a75c     perfts!CloseLagPerfData+0x21
03 00000000`33ccda30 00007ffd`85209ccd     advapi32!CloseExtObjectLibrary+0xec
04 00000000`33ccda90 00007ffd`8396dc6a     advapi32!PerfRegCloseKey+0x15d
05 00000000`33ccdae0 00007ffd`839715e6     KERNELBASE!BaseRegCloseKeyInternal+0x72
06 00000000`33ccdb10 00007ffd`83935209     KERNELBASE!ClosePredefinedHandle+0x96
07 00000000`33ccdb40 00007ffd`53685d71     KERNELBASE!RegCloseKey+0x149
08 00000000`33ccdba0 00007ffd`53683ae5     AcLayers!NS_VirtualRegistry::CVirtualRegistry::CloseKey+0xbd
09 00000000`33ccdbf0 00007ffd`51c7737e     AcLayers!NS_VirtualRegistry::APIHook_RegCloseKey+0x25
0a 00000000`33ccdc30 00007ffd`51bf4be2     mscorlib_ni+0x58737e
0b 00000000`33ccdce0 00007ffd`513c356a     mscorlib_ni!Microsoft.Win32.RegistryKey.Dispose+0x72
0c 00000000`33ccdd20 00007ffd`513c34b9     System_ni!System.Diagnostics.PerformanceCounterLib.GetStringTable+0x41a
...
13 00000000`33cce050 00007ffd`513bfe3c     System_ni!System.Diagnostics.PerformanceCounter..ctor+0xd7
14 00000000`33cce0a0 00007ffc`f45cb2ce     System_ni!System.Diagnostics.PerformanceCounter..ctor+0x1c
15 00000000`33cce0d0 00007ffc`f45cb14c     0x00007ffc`f45cb2ce
16 00000000`33cce120 00007ffc`f45cb023     0x00007ffc`f45cb14c
...

从卦中看,这个线程貌似在用 CloseLagPerfData 方法关闭一些东西时一直在Sleep等待,可以反汇编 00007ffd6d4a2361 处代码看看等待多久。


0:028> ub 00007ffd`6d4a2361
perfts!CloseLagPerfData+0x5:
00007ffd`6d4a2345 55              push    rbp
00007ffd`6d4a2346 488bec          mov     rbp,rsp
00007ffd`6d4a2349 4883ec30        sub     rsp,30h
00007ffd`6d4a234d e8720e0000      call    perfts!LagCounterManager::Cleanup (00007ffd`6d4a31c4)
00007ffd`6d4a2352 33db            xor     ebx,ebx
00007ffd`6d4a2354 eb0b            jmp     perfts!CloseLagPerfData+0x21 (00007ffd`6d4a2361)
00007ffd`6d4a2356 b964000000      mov     ecx,64h
00007ffd`6d4a235b ff15c74e0000    call    qword ptr [perfts!_imp_Sleep (00007ffd`6d4a7228)]
...

从卦中的 mov ecx,64h 可以看到是 Sleep(100) 毫秒,更多细节也没空继续追究了,但不管怎么样,它是由上层的计数器类 PerformanceCounter引发的,这里学一下 4S 店的做法,让朋友能不能不要调用 PerformanceCounter 这个类,咱躲开他就可以了,截图如下:

去掉之后,朋友反馈问题消失。

三:总结

说来也奇怪,最近发现了二起由 PerformanceCounter 引发的程序卡死,把经验留在这里,希望后来人少踩坑吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1528268.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

旅游行业分析及媒体邀约资源汇总

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 酒店旅游行业分析及媒体邀约资源汇总是两个相对独立但又相互关联的领域。下面将分别对这两个方面进行概述。 酒店旅游行业分析 1. 市场概况 市场规模&#xff1a;评估市场的总价值、增长…

【python】学习笔记04-函数

4.1 函数介绍 1. 函数是&#xff1a; 组织好的、可重复使用的、用来实现特定功能的代码段 2. 使用函数的好处是&#xff1a; • 将功能封装在函数内&#xff0c;可供随时随地重复利用 • 提高代码的复用性&#xff0c;减少重复代码&#xff0c;提高开发效率 4.2 函数的定义 …

视频桥接芯片#LT8912B适用于MIPIDSI转HDMI+LVDS应用方案,提供技术支持。

1. 概述 Lontium LT8912B MIPI DSI 转 LVDS 和 HDMI 桥接器采用单通道 MIPI D-PHY 接收器前端配置&#xff0c;每通道 4 个数据通道&#xff0c;每个数据通道以 1.5Gbps 的速度运行&#xff0c;最大输入带宽高达 6Gbps。 对于屏幕应用&#xff0c;该桥接器可解码 MIPI DSI 18bp…

聚合音乐网-播放器网站源码

源码简介 MKOnlineMusicPlayer 是一款全屏的音乐播放器 UI 框架&#xff08;为避免侵权&#xff0c;已移除所有后端功能&#xff09;。 前端界面参照 QQ 音乐网页版进行布局&#xff0c;同时采用了流行的响应式设计&#xff0c;无论是在PC端还是在手机端&#xff0c;均能给您…

Excel之数据透视表

数据透视&#xff1a;逻辑理解与制作步骤 一、创建数据透视表 1、创建数据透视表&#xff1a;每列必须有表头 &#xff08;1&#xff09;选择要创建数据透视表的数据------插入----选择数据透视表 &#xff08;2&#xff09;选择现有工作表然后点击目标表选择合适的位置插入…

工控机丨工业平板电脑丨工业计算机丨物流行业应用

随着物流业的发展&#xff0c;工控机在物流领域的应用越来越广泛。工控机是指用于控制工业自动化和机器 人技术的计算机&#xff0c;具有高稳定性、高性能和高可靠性等特点。下面将从几个方面介绍工控机在物流行业中的应用。 一、物流信息管理 工控机可以用于物流信息管理&am…

LLM流式方案解决方案和客户端解决方案

背景 接上一篇《LLM大模型统一封装接口解决方案》架构确定后&#xff0c;流式方案非常规请求&#xff0c;需要特殊处理。 本解决方案就是针对上一篇中所需要的流式&#xff08;打字机效果进行编码&#xff09; 什么是SSE SSE&#xff08;Server-Sent Events&#xff0c;服务器发…

【靶机测试--PHOTOGRAPHER: 1【php提权】】

前期准备 靶机下载地址&#xff1a; https://vulnhub.com/entry/photographer-1%2C519/ 信息收集 nmap 扫描同网段 ┌──(root㉿kali)-[/home/test/桌面] └─# nmap -sP 192.168.47.0/24 --min-rate 3333 Starting Nmap 7.92 ( https://nmap.org ) at 2024-03-19 07:37 …

数学建模软件及算法模型典型问题汇总

一、 软件篇 编程、MATLAB&#xff08;物理建模&#xff09;、python&#xff08;数据分析&#xff09;、R、其他&#xff08;SPSS、Stata、Origin&#xff09; 这里其实还有一个 Lingo 软件&#xff0c;不过我不推荐&#xff0c;有更好的替代方案&#xff0c;就是 Yalmip 工…

React的基本使用

安装VSCode插件 ES7 Reactopen in browser React基本使用 基本使用步骤 引入两个JS文件&#xff08; 注意引入顺序 &#xff09; <!-- react库, 提供React对象 --> //本地 <script src"../js/react.development.js"></script> //线上 //<scr…

理解和调试深度学习模型:探索人工智能可解释性方法

关键要点 深度学习模型可能非常复杂&#xff0c;理解其内部原理可能具有挑战性在机器学习中&#xff0c;提供可解释性的方法有多种为了确保这些自动化系统的可靠性&#xff0c;可以使用可解释性工具来深入了解模型的决策过程模型不可知的可解释性工具在不同模型之间是模块化的…

如何判断竞价托管代运营公司或SEM营销优化师水平高低

竞价托管代运营公司或营销优化师的能力评估需要从多个角度来考虑&#xff0c;通常有以下几种评估方式&#xff0c;一般来说&#xff0c;按照遨游建站多年经验来分析评估比较靠谱&#xff0c;对于不懂SEM的人来说也最适合&#xff0c;不需要许多专业的知识&#xff0c;也能判断出…

深度强化学习05策略学习

蒙特卡洛近似 梯度上升 总结

C语言项目:数组与函数实践:扫雷游戏

目录 目录&#xff1a; 1.扫雷游戏分析与设计 1.1扫雷游戏的功能说明&#xff1a; 1.1.1使用控制台实现经典扫雷的游戏 1.1.2游戏可以通过菜单实现继续玩或者退出游戏 1.1.3扫雷棋盘是9*9的格子 1.1.4默认随机布置10个雷 1.1.5 可以排查雷 2.扫雷游戏的代码实现 1.遇到的问题…

Latex插入pdf图片,去除空白部分

目录 参考链接&#xff1a; 流程&#xff1a; 参考链接&#xff1a; ​科研锦囊之Latex-如何插入图片、表格、参考文献 http://t.csdnimg.cn/vpSJ3 流程&#xff1a; Latex的图片插入支持PDF文件&#xff0c;这里笔者建议都使用PDF文件进行图片的插入&#xff0c;因为PDF作…

SinoDB数据库运行分析

SinoDB数据库运行主要从数据库互斥资源等待、数据库写类型、备份文件有效性、Chunk状态等15个方向进行分析&#xff0c;具体说明如下&#xff1a; 一、数据库互斥资源等待 检查项目 数据库互斥资源等待 检查命令 onstat -g con |head -20 说明 onstat -g con 查看目前数据处…

【C++练级之路】【Lv.14】二叉搜索树(进化的二叉树——BST)

快乐的流畅&#xff1a;个人主页 个人专栏&#xff1a;《C语言》《数据结构世界》《进击的C》 远方有一堆篝火&#xff0c;在为久候之人燃烧&#xff01; 文章目录 引言一、二叉搜索树介绍二、二叉搜索树的模拟实现2.1 结点2.2 成员变量2.3 默认成员函数2.3.1 constructor2.3.2…

汽车功能安全整体方法

摘 要 ISO26262道路车辆功能安全标准已经制定实践了多年&#xff0c;主要目标是应对车辆的电子和电气&#xff08;E/E&#xff09;系统失效。该方法践行至今&#xff0c;有些系统功能安全方法已经成熟&#xff0c;例如电池管理系统&#xff08;BMS&#xff09;&#xff0c;并且…

MindGraph:文字生成知识图

欢迎来到MindGraph&#xff0c;这是一个概念验证、开源的、以API为先的基于图形的项目&#xff0c;旨在通过自然语言的交互&#xff08;输入和输出&#xff09;来构建和定制CRM解决方案。该原型旨在便于集成和扩展。以下是关于X的公告&#xff0c;提供更多背景信息。开始之前&a…

每日OJ题_牛客HJ75 公共子串计算(IO型OJ)

目录 牛客HJ75 公共子串计算 解析代码 牛客HJ75 公共子串计算 公共子串计算_牛客题霸_牛客网 解析代码 #include <iostream> using namespace std; int main() {string str1 "", str2 "";cin >> str1 >> str2;int n1 str1.size()…