记一次 Visual Studio 2022 卡死分析

一:背景

1. 讲故事

最近不知道咋了,各种程序有问题都寻上我了,你说 .NET 程序有问题找我能理解,Windows 崩溃找我,我也可以试试看,毕竟对 Windows 内核也知道一丢丢,那 Visual Studio 有问题找我就说不过去了,但又不好拒绝,就让朋友发下卡死的 dump 我看一看。

二:WinDbg 分析

1. 到底是哪里的卡死

因为 VS 是窗体程序,所以在卡死的时候看下主线程便知,使用 ~0s;!clrstack 即可。

0:000> k
 # Child-SP          RetAddr               Call Site
00 0000004b`acaf9b90 000001ed`309f0f28     0x00007ffb`1b77bfe8
01 0000004b`acaf9b98 00007ffb`4a03e397     0x000001ed`309f0f28
02 0000004b`acaf9ba0 00007ffb`4a04c08e     PresentationFramework_ni!System.Windows.Controls.ItemContainerGenerator.DoLinearSearch+0x1d7
03 0000004b`acaf9c70 00007ffb`4ab3bd36     PresentationFramework_ni!System.Windows.Controls.ItemContainerGenerator.ContainerFromItem+0x8e
04 0000004b`acaf9ce0 00007ffb`4ab3bd6e     PresentationFramework_ni!System.Windows.Automation.Peers.ItemAutomationPeer.GetWrapper+0xc6
05 0000004b`acaf9d20 00007ffb`4ab3c94f     PresentationFramework_ni!System.Windows.Automation.Peers.ItemAutomationPeer.GetWrapperPeer+0xe
06 0000004b`acaf9d60 00007ffb`4ba3f72c     PresentationFramework_ni!System.Windows.Automation.Peers.ItemAutomationPeer.IsControlElementCore+0xf
07 0000004b`acaf9d90 00007ffb`4ba42026     PresentationCore_ni!System.Windows.Automation.Peers.AutomationPeer.IsControlElement+0x3c
08 0000004b`acaf9de0 00007ffb`4ba41e8b     PresentationCore_ni!System.Windows.Automation.Peers.AutomationPeer.IsControlElement+0x36
09 0000004b`acaf9e20 00007ffb`4bcc5632     PresentationCore_ni!System.Windows.Automation.Peers.AutomationPeer.GetPropertyValue+0x7b
0a 0000004b`acaf9e70 00007ffb`4c182cf8     PresentationCore_ni!MS.Internal.Automation.ElementUtil.<>c__DisplayClass11_0.<Invoke>b__0+0x32
0b 0000004b`acaf9eb0 00007ffb`4c182bf6     WindowsBase_ni!System.Windows.Threading.ExceptionWrapper.InternalRealCall+0x68
0c 0000004b`acaf9f20 00007ffb`4c180202     WindowsBase_ni!System.Windows.Threading.ExceptionWrapper.TryCatchWhen+0x36
0d 0000004b`acaf9f70 00007ffb`4bca4423     WindowsBase_ni!System.Windows.Threading.Dispatcher.LegacyInvokeImpl+0x172
0e 0000004b`acafa010 00007ffb`480629e1     PresentationCore_ni!MS.Internal.Automation.ElementUtil.Invoke+0xb3
0f 0000004b`acafa070 00007ffb`7af71059     UIAutomationTypes_ni+0x729e1
10 0000004b`acafa0e0 00007ffb`7ae13eba     clr!COMToCLRDispatchHelper+0x39
11 0000004b`acafa110 00007ffb`7af70fb7     clr!COMToCLRWorker+0x1ea
12 0000004b`acafa1b0 00007ffb`625b4cc9     clr!GenericComCallStub+0x57
...

我丢,这线程栈一看有意外发现哈,这 PresentationCore_ni 不是 WPF 的专用库嘛,下面还有 clr ,看样子 VS 的UI是 WPF 写的,顿时有一种亲切感,那既然是 .NET 程序我还是可以分析的。

进一步观察线程栈,可以看到它没有非托管的部分,诸如:user32.dllntdll.dll,也就说明此时的卡死只是托管层面,接下来使用 sos 专有的 !clrstack 观察,删减后如下:

0:000> !clrstack
OS Thread Id: 0x8144 (0)
        Child SP               IP Call Site
0000004bacafa220 00007ffb1b77bfe8 [ComMethodFrame: 0000004bacafa220] 
0000004bacafb0d8 00007ffb1b77bfe8 [InlinedCallFrame: 0000004bacafb0d8] MS.Win32.UnsafeNativeMethods.OleSetClipboard(System.Runtime.InteropServices.ComTypes.IDataObject)
0000004bacafb0d8 00007ffb4c357e22 [InlinedCallFrame: 0000004bacafb0d8] MS.Win32.UnsafeNativeMethods.OleSetClipboard(System.Runtime.InteropServices.ComTypes.IDataObject)
0000004bacafb0a0 00007ffb4c357e22 DomainNeutralILStubClass.IL_STUB_PInvoke(System.Runtime.InteropServices.ComTypes.IDataObject)
0000004bacafb180 00007ffb4ba0f5ed System.Windows.Clipboard.CriticalSetDataObject(System.Object, Boolean)
0000004bacafb1c0 00007ffae3b1bd6a Microsoft.VisualStudio.Text.Utilities.WpfClipboardService.SetData(System.String, System.String, System.String, Boolean, System.String, Boolean, Boolean)
0000004bacafb210 00007ffae3b1bc1c Microsoft.VisualStudio.Text.Operations.Implementation.EditorOperations.CopyToClipboard(System.String, System.String, Boolean, Boolean)
0000004bacafb270 00007ffae3b199a2 Microsoft.VisualStudio.Text.Operations.Implementation.EditorOperations+c__DisplayClass176_0.b__0()
0000004bacafb2a0 00007ffae3b196ca Microsoft.VisualStudio.Text.Operations.Implementation.EditorOperations.CopySelection()
...
0000004bacafcc20 00007ffb2edd765b JetBrains.ReSharper.Feature.Services.Clipboard.CopyPasteAssistManager.DoCopyOrCut(JetBrains.Application.DataContext.IDataContext, JetBrains.Application.UI.Actions.DelegateExecute)
0000004bacafcc70 00007ffb2edd7628 JetBrains.ReSharper.Feature.Services.Clipboard.CopyPasteAssistManager.DoCopyOrCut(JetBrains.Application.DataContext.IDataContext, JetBrains.Application.UI.Actions.DelegateExecute)
0000004bacafcd00 00007ffb2edd5407 JetBrains.ReSharper.InplaceRefactorings.CutCopyPaste.CopyPasteManager.DoCopyOrCut(JetBrains.Application.DataContext.IDataContext, Boolean, JetBrains.Application.UI.Actions.DelegateExecute)
0000004bacafcd70 00007ffb2edd53c4 JetBrains.ReSharper.InplaceRefactorings.CutCopyPaste.CopyPasteManager.DoCopyOrCut(JetBrains.Application.DataContext.IDataContext, Boolean, JetBrains.Application.UI.Actions.DelegateExecute)
0000004bacafce50 00007ffb2edd4d88 JetBrains.ReSharper.Feature.Services.Clipboard.ClipboardActionHandler.Execute(JetBrains.Application.DataContext.IDataContext, JetBrains.Application.UI.Actions.DelegateExecute)
...
0000004bacafdc40 00007ffb2268a2da DomainNeutralILStubClass.IL_STUB_COMtoCLR(IntPtr, Int32, Int32, Int64, Int64)
0000004bacafde00 00007ffb7af71011 [ComMethodFrame: 0000004bacafde00] 

从卦中看,是在处理剪贴板OleSetClipboard的逻辑中一直出不来,而且还有一个外来的 JetBrains.ReSharper 插件,看样子朋友的某些操作让 Resharper 介入了。

为了进一步验证是不是 Resharper 导致的,可以根据 ip 找到所属的模块。

0:000> !ip2md 00007ffb2edd5407
MethodDesc:   00007ffb28e984b0
Method Name:  JetBrains.ReSharper.InplaceRefactorings.CutCopyPaste.CopyPasteManager.DoCopyOrCut(JetBrains.Application.DataContext.IDataContext, Boolean, JetBrains.Application.UI.Actions.DelegateExecute)
Class:        00007ffb28ea1b40
MethodTable:  00007ffb28e98578
mdToken:      00000000060000aa
Module:       00007ffb201c48b8
IsJitted:     yes
CodeAddr:     00007ffb2edd4f60
Transparency: Critical
0:000> !DumpModule /d 00007ffb201c48b8
Name:       C:\Users\Administrator\AppData\Local\JetBrains\Installations\ReSharperPlatformVs17_265273ed_001\JetBrains.ReSharper.InplaceRefactorings.dll
Attributes: PEFile SupportsUpdateableMethods
Assembly:   000001edb0cce780
LoaderHeap:              0000000000000000
TypeDefToMethodTableMap: 00007ffb201d0020
TypeRefToMethodTableMap: 00007ffb201d03a8
MethodDefToDescMap:      00007ffb201d10a0
FieldDefToDescMap:       00007ffb201d21c0
MemberRefToDescMap:      0000000000000000
FileReferencesMap:       00007ffb201d2ae0
AssemblyReferencesMap:   00007ffb201d2ae8
MetaData start address:  000001edb6b8a960 (103320 bytes)

从卦中的 Name 来看,再一次确认了 ReSharper 的问题。

2. ReSharper 是阻塞还是死锁

本着 4S 店只换不修的思路,让朋友直接卸载掉VS中的 ReSharper 肯定是没问题的,但为了兴趣继续探究下 Resharper 正在做什么?

从汇编代码看,当前正准备做两个 if 判断,而且都是 true,最后跳转到 IGeneratorHost.View 属性中,不管怎么说,这里还是不断的处理,所以我觉得这里的阻塞要么是 死循环 出不来,要么还需要再等等。

可能有些朋友好奇,Resharper 塞入到剪贴板中到底是什么数据,要想挖这个信息,可以看汇编从线程栈提取,这次就不搞这么复杂了,换个思路吧,先看 CriticalSetDataObject 方法源码,输出如下:

internal static void CriticalSetDataObject(object data, bool copy)
{

    IComDataObject dataObject;

    if (data is DataObject)
    {
        dataObject = (DataObject)data;
    }
    else if (data is IComDataObject)
    {
        SecurityHelper.DemandUnmanagedCode();
        dataObject = (IComDataObject)data;
    }
    else
    {
        dataObject = new DataObject(data);
    }
    ...
}

接下来用 !dso 看下有没有类似的 DataObject 和 IComDataObject 对象,输出如下:

0:000> !dso
OS Thread Id: 0x8144 (0)
RSP/REG          Object           Name
...
0000004BACAFB138 000001ed401e9ec8 System.Windows.DataObject
...

0:000> !mdt 000001ed401e9ec8
000001ed401e9ec8 (System.Windows.DataObject)
    _innerData:000001ed401e9ee0 (System.Windows.DataObject+DataStore)
0:000> !mdt 000001ed401e9ee0
000001ed401e9ee0 (System.Windows.DataObject+DataStore)
    _data:000001ed401e9ef8 (System.Collections.Hashtable)
0:000> !mdt 000001ed401e9ef8
000001ed401e9ef8 (System.Collections.Hashtable)
    buckets:000001ed401e9f48 (System.Collections.Hashtable+bucket[], Elements: 3, ElementMT=00007ffb79123af8)
    count:0x2 (System.Int32)
    occupancy:0x1 (System.Int32)
    loadsize:0x2 (System.Int32)
    loadFactor:0.720000 (System.Single)
    version:0x2 (System.Int32)
    isWriterInProgress:false (System.Boolean)
    keys:NULL (System.Collections.ICollection)
    values:NULL (System.Collections.ICollection)
    _keycomparer:NULL (System.Collections.IEqualityComparer)
    _syncRoot:NULL (System.Object)
expand all 2 items   
0:000> !mdt 000001ed401e9f48
000001ed401e9f48 (System.Collections.Hashtable+bucket[], Elements: 3, ElementMT=00007ffb79123af8)
expand all 3 items   
0:000> !mdt -e:2 000001ed401e9f48
000001ed401e9f48 (System.Collections.Hashtable+bucket[], Elements: 3, ElementMT=00007ffb79123af8)
[0] (System.Collections.Hashtable+bucket) VALTYPE (MT=00007ffb79123af8, ADDR=000001ed401e9f58)
    key:000001ed310ea6f0 (System.String) Length=11, String="UnicodeText"
    val:000001ed401e9fd0 (System.Windows.DataObject+DataStore+DataStoreEntry[], Elements: 1)
    hash_coll:0xf337c502 (System.Int32)
[1] (System.Collections.Hashtable+bucket) VALTYPE (MT=00007ffb79123af8, ADDR=000001ed401e9f70)
    key:000001ed310eaa08 (System.String) Length=16, String="Rich Text Format"
    val:000001ed401ea018 (System.Windows.DataObject+DataStore+DataStoreEntry[], Elements: 1)
    hash_coll:0x30818946 (System.Int32)
[2] (System.Collections.Hashtable+bucket) VALTYPE (MT=00007ffb79123af8, ADDR=000001ed401e9f88)
    key:NULL (System.Object)
    val:NULL (System.Object)
    hash_coll:0x0 (System.Int32)
increase depth
0:000> !mdt 000001ed401ea018
000001ed401ea018 (System.Windows.DataObject+DataStore+DataStoreEntry[], Elements: 1)
expand all 1 items   
0:000> !mdt -e:2 000001ed401ea018
000001ed401ea018 (System.Windows.DataObject+DataStore+DataStoreEntry[], Elements: 1)
[0] 000001ed401e9ff0 (System.Windows.DataObject+DataStore+DataStoreEntry)
    _data:000001ed401635e8 (System.String) Length=1165, String="{\rtf\ansi{\fonttbl{\f0 NSimSun;}}{\colortbl;\red0\green0\blue255;\red0\green0\blue0;\red0\green128\blue0;}\f0 \fs19 \cf1 \cb0 \highlight0 var\cf2  hostname = System.Net.Dns.GetHostName();\par                 System.Net.IPAddress[] hostaddrs = System.Net.Dns.GetHostAddresses(hostname);\par \par                 \cf1 var\cf2  localIPList = \cf1 new\cf2  List<IPAddress>();\par                 \cf1 for\cf2  (\cf1 int\cf2  i = 0; i < hostaddrs.Length; i++)\par                 \{\par                     \cf1 if\cf2  (System.Net.Sockets.AddressFamily.InterNetwork == hostaddrs[i].AddressFamily)\par                     \{\par                         \cf1 if\cf2  (hostaddrs[i].ToString().Equals(_localIP))\par                         \{\par                             localIPList.Insert(0, hostaddrs[i]);\cf3 //\uc1\u20248?\uc1\u20808?\uc1\u20351?\uc1\u29992?\uc1\u19978?\uc1\u27425?\uc1\u-28706?\uc1\u25509?IP\cf2 \par                         \}\par                         \cf1 else\cf2 \par                         \{\par                             localIPList.Add(hostaddrs[i]);\par                         \}\par                     \}\par                 \}}"
    _autoConvert:true (System.Boolean)
    _aspect:0x1 (System.Runtime.InteropServices.ComTypes.DVASPECT)
    _index:0x0 (System.Int32)
increase depth

简单整理了下大概是这样的代码。

            var hostname = System.Net.Dns.GetHostName();
            System.Net.IPAddress[] hostaddrs = System.Net.Dns.GetHostAddresses(hostname);

            var localIPList = new List<IPAddress>();
            for (int i = 0; i < hostaddrs.Length; i++)
            {
                if (System.Net.Sockets.AddressFamily.InterNetwork == hostaddrs[i].AddressFamily)
                {
                    if (hostaddrs[i].ToString().Equals(_localIP))
                    {
                        localIPList.Insert(0, hostaddrs[i]);//优先使用上次连接IP
                    }
                    else
                    {
                        localIPList.Add(hostaddrs[i]);
                    }
                }
            }

有了这些信息,还是先让朋友把 Reshaper 卸载掉看看,据朋友反馈在 Resharper 官方的 issue 里找到了解决方案,禁用了如下选项,暂时没有出现任何问题,截图如下:

三:总结

综合朋友的反馈,这次VS的卡死就是他按下了 Ctrl+C 复制这段代码的时候,Resharper 插件介入,然后在处理富文本时出问题了,不知道大家可踩过类似的坑,算是给后来人一点定位经验吧。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用JMX管理Spring Bean

1.使用JMX管理Spring Bean 2.spring通过annotation注解注册MBean到JMX实现监控java运行状态 3.Spring与JMX集成

Elastic 推出 Elastic AI 助手

作者&#xff1a;Mike Nichols Elastic 推出了 Elastic AI Assistant&#xff0c;这是一款由 ESRE 提供支持的开放式、生成式 AI 助手&#xff0c;旨在使网络安全民主化并支持各种技能水平的用户。 最近发布的 Elasticsearch Relevance Engine™ (ESRE™) 提供了用于创建高度相…

Keil环境下CANopenNode移植到STM32问题记录(一)---printf重定向问题

文章目录 问题描述问题结决思考&#xff1a;相关文章 在直接将CANopenSTM32的示例工程直接移植到Keil环境下。 如果移植工程未实现printf函数重定向&#xff0c;则要注释掉log_printf下面的printf函数&#xff0c;使日志打印失效 /* Printf function of CanOpen app */ #define…

第七章:L2JMobius学习 – 登录服务LoginServer讲解

在上一个章节中&#xff0c;我们学习了网络数据传输的封装network。那么&#xff0c;在本章的登录服务LoginServer的讲解中&#xff0c;我们就来使用一下这个封装好的功能。Network的封装需要我们继承很多的接口或类。我们首先查看一下登录服务LoginServer的文件结构&#xff0…

DotNet VOL.Core框架学习使用笔记(二)(持续更新)

2023-7-5 生成代码的列表界面&#xff0c;在数据行里增加一个操作列 查看按钮&#xff0c;打开编辑框&#xff0c;然后让编辑框成为一个只读的查看界面。 页面对应的js文件中增加如下 this.columns.push 函数内容。 按钮的点击事件 重点代码 this.edit(row); 这就是框架里编…

天翎群晖NAS为全文检索插翅起飞

编者按&#xff1a;企业的文档资料随着企业的业务发展会越来越多&#xff0c;想要某个资料的时候&#xff0c;最怕找不到想要的资料&#xff0c;这时KMS的全文检索功能就非常重要了&#xff0c;只需只言片语的零星关键字&#xff0c;查找文档没压力。 关键词&#xff1a;全文检…

MySQL练习题(1)

1,创建如下学生表 mysql> create table student( -> id int, -> name varchar(20), -> gender varchar(20), -> chinese int, -> math int, -> english int -> ); 插入如图数据 1-- 查询表中所有学生的信息 select *from student;2-- 查询表中所有学…

TypeScript 总结

文章目录 TypeScript 总结概述运行ts文件方式一方式二 基础声明变量类型数组元组联合类型取值限制 枚举类型any & unknownvoid & undefined类型适配 面向对象函数普通函数箭头函数可选参数默认参数 对象创建对象对象的类型限制 类和接口泛型简单使用多个泛型默认泛型类…

集合处理常用Stream流

集合处理常用Stream流 1、Stream API介绍2、List集合常用Stream方法 stream流经常使用&#xff0c;但是遇到一些流操作时&#xff0c;会一下想不到用哪种&#xff0c;这里总结一下&#xff0c;方便自己或者读者查找 1、Stream API介绍 Stream API是Java 8引入的一项重要特性&a…

vue对于数组的数据监听变化和object是不一样的吗?

我们知道vue对于数组的数据监听变化和object是不一样的&#xff0c;因为我们常说的Object.defineProperty是对象上面的方法&#xff0c;所以对于array数组需要实现另外一套变化侦测机制。 今天我们就来研究下。 在哪里收集依赖 array数据设计了新的变化侦测机制&#xff0c;…

10个图像处理的Python库

在这篇文章中&#xff0c;我们将整理计算机视觉项目中常用的Python库&#xff0c;如果你想进入计算机视觉领域&#xff0c;可以先了解下本文介绍的库&#xff0c;这会对你的工作很有帮助。 1、PIL/Pillow Pillow是一个通用且用户友好的Python库&#xff0c;提供了丰富的函数集…

QT day1简单登录界面

widget.cpp文件代码&#xff1a; #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget) {qDebug()<<this->size();qDebug()<<this->frameSize();this->setFixedSize(50…

如何用Python搭建监控平台

监控和运维&#xff0c;是互联网工业链上非常重要的一环。监控的目的就是防患于未然。通过监控&#xff0c;我们能够及时了解到企业网络的运行状态。一旦出现安全隐患&#xff0c;你就可以及时预警&#xff0c;或者是以其他方式通知运维人员&#xff0c;让运维监控人员有时间处…

MATLAB 之 可视化图形用户界面设计

这里写目录标题 一、可视化图形用户界面设计1. 图形用户界面设计窗口1.1 图形用户界面设计模板1.2 图形用户界面设计窗口 2. 可视化图形用户界面设计工具1.1 对象属性检查器2.2 菜单编辑器2.3 工具栏编辑器2.4 对齐对象工具2.5 对象浏览器2.6 Tab 键顺序编辑器 3. 可视化图形用…

多元分类预测 | Matlab基于北方苍鹰优化深度置信网络(NGO-DBN)的分类预测,多输入模型,NGO-DBN分类预测

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元分类预测 | Matlab基于北方苍鹰优化深度置信网络(NGO-DBN)的分类预测,多输入模型,NGO-DBN分类预测 多特征输入单输出的二分类及多分类模型。程序内注释详细,直接替换数据就可以用。程序语言为matlab,程序可…

地下饮用水除硝酸盐技术、生活用水提质增效

项目名称 北京某地下水除硝酸盐项目&#xff0c;出水未检出 工艺选择 两处水源&#xff0c;运行方式为一用一备 工艺原理 树脂官能团耐受硫酸盐、氯离子的干扰&#xff0c;实现选择性吸附硝酸根 项目背景 近年来由于农业活动及排污物的影响&#xff0c;部分地表…

【STM32】STM32G系列使用CORDIC模块加速计算

1.前言 STM32G431系列产品内置了CORDIC运算单元&#xff0c;可以用来加速数学计算&#xff0c;如三角函数、取模、开方等。适合大量数据进行相同的运算操作。配合DMA可以大大节省CPU计算开销。 2.CubeMX配置 使用CORDIC模块无需配置参数&#xff0c;若采用DMA方式则只需配置…

多元分类预测 | Matlab基于灰狼优化深度置信网络(GWO-DBN)的分类预测,多特征输入模型,GWO-DBN分类预测

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元分类预测 | Matlab基于灰狼优化深度置信网络(GWO-DBN)的分类预测,多特征输入模型,GWO-DBN分类预测 多特征输入单输出的二分类及多分类模型。程序内注释详细,直接替换数据就可以用。程序语言为matlab,程序可…

如何提高OAK相机在树莓派和JETSON上的运行帧率?

编辑&#xff1a;OAK中国 首发&#xff1a;oakchina.cn 喜欢的话&#xff0c;请多多&#x1f44d;⭐️✍ 内容可能会不定期更新&#xff0c;官网内容都是最新的&#xff0c;请查看首发地址链接。 Hello&#xff0c;大家好&#xff0c;这里是OAK中国&#xff0c;我是助手君。 最…

【嵌入式Qt开发入门】如何使用Qt进行绘制实时图表——QChart 图表

要想使用 Qt Charts&#xff0c;我们的 Qt 版本得使用 Qt 5.7 之后的版本。其实 Qt Charts 并不是 Qt 5.7 才有的&#xff0c;是在 Qt 5.7 以前只有商业版本的 Qt 才有 Qt Charts。我们能免费下载的 Qt 版本都是社区&#xff08;开源&#xff09;版本。 Qt Charts 很方便的绘制…