经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 软件/图像 » Visual Studio » 查看文章
记一次 Visual Studio 2022 卡死分析
来源:cnblogs  作者:一线码农  时间:2023/5/19 9:11:21  对本文有异议

一:背景

1. 讲故事

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

二:WinDbg 分析

1. 到底是哪里的卡死

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

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

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

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

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

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

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

  1. 0:000> !ip2md 00007ffb2edd5407
  2. MethodDesc: 00007ffb28e984b0
  3. Method Name: JetBrains.ReSharper.InplaceRefactorings.CutCopyPaste.CopyPasteManager.DoCopyOrCut(JetBrains.Application.DataContext.IDataContext, Boolean, JetBrains.Application.UI.Actions.DelegateExecute)
  4. Class: 00007ffb28ea1b40
  5. MethodTable: 00007ffb28e98578
  6. mdToken: 00000000060000aa
  7. Module: 00007ffb201c48b8
  8. IsJitted: yes
  9. CodeAddr: 00007ffb2edd4f60
  10. Transparency: Critical
  11. 0:000> !DumpModule /d 00007ffb201c48b8
  12. Name: C:\Users\Administrator\AppData\Local\JetBrains\Installations\ReSharperPlatformVs17_265273ed_001\JetBrains.ReSharper.InplaceRefactorings.dll
  13. Attributes: PEFile SupportsUpdateableMethods
  14. Assembly: 000001edb0cce780
  15. LoaderHeap: 0000000000000000
  16. TypeDefToMethodTableMap: 00007ffb201d0020
  17. TypeRefToMethodTableMap: 00007ffb201d03a8
  18. MethodDefToDescMap: 00007ffb201d10a0
  19. FieldDefToDescMap: 00007ffb201d21c0
  20. MemberRefToDescMap: 0000000000000000
  21. FileReferencesMap: 00007ffb201d2ae0
  22. AssemblyReferencesMap: 00007ffb201d2ae8
  23. MetaData start address: 000001edb6b8a960 (103320 bytes)

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

2. ReSharper 是阻塞还是死锁

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

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

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

  1. internal static void CriticalSetDataObject(object data, bool copy)
  2. {
  3. IComDataObject dataObject;
  4. if (data is DataObject)
  5. {
  6. dataObject = (DataObject)data;
  7. }
  8. else if (data is IComDataObject)
  9. {
  10. SecurityHelper.DemandUnmanagedCode();
  11. dataObject = (IComDataObject)data;
  12. }
  13. else
  14. {
  15. dataObject = new DataObject(data);
  16. }
  17. ...
  18. }

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

  1. 0:000> !dso
  2. OS Thread Id: 0x8144 (0)
  3. RSP/REG Object Name
  4. ...
  5. 0000004BACAFB138 000001ed401e9ec8 System.Windows.DataObject
  6. ...
  7. 0:000> !mdt 000001ed401e9ec8
  8. 000001ed401e9ec8 (System.Windows.DataObject)
  9. _innerData:000001ed401e9ee0 (System.Windows.DataObject+DataStore)
  10. 0:000> !mdt 000001ed401e9ee0
  11. 000001ed401e9ee0 (System.Windows.DataObject+DataStore)
  12. _data:000001ed401e9ef8 (System.Collections.Hashtable)
  13. 0:000> !mdt 000001ed401e9ef8
  14. 000001ed401e9ef8 (System.Collections.Hashtable)
  15. buckets:000001ed401e9f48 (System.Collections.Hashtable+bucket[], Elements: 3, ElementMT=00007ffb79123af8)
  16. count:0x2 (System.Int32)
  17. occupancy:0x1 (System.Int32)
  18. loadsize:0x2 (System.Int32)
  19. loadFactor:0.720000 (System.Single)
  20. version:0x2 (System.Int32)
  21. isWriterInProgress:false (System.Boolean)
  22. keys:NULL (System.Collections.ICollection)
  23. values:NULL (System.Collections.ICollection)
  24. _keycomparer:NULL (System.Collections.IEqualityComparer)
  25. _syncRoot:NULL (System.Object)
  26. expand all 2 items
  27. 0:000> !mdt 000001ed401e9f48
  28. 000001ed401e9f48 (System.Collections.Hashtable+bucket[], Elements: 3, ElementMT=00007ffb79123af8)
  29. expand all 3 items
  30. 0:000> !mdt -e:2 000001ed401e9f48
  31. 000001ed401e9f48 (System.Collections.Hashtable+bucket[], Elements: 3, ElementMT=00007ffb79123af8)
  32. [0] (System.Collections.Hashtable+bucket) VALTYPE (MT=00007ffb79123af8, ADDR=000001ed401e9f58)
  33. key:000001ed310ea6f0 (System.String) Length=11, String="UnicodeText"
  34. val:000001ed401e9fd0 (System.Windows.DataObject+DataStore+DataStoreEntry[], Elements: 1)
  35. hash_coll:0xf337c502 (System.Int32)
  36. [1] (System.Collections.Hashtable+bucket) VALTYPE (MT=00007ffb79123af8, ADDR=000001ed401e9f70)
  37. key:000001ed310eaa08 (System.String) Length=16, String="Rich Text Format"
  38. val:000001ed401ea018 (System.Windows.DataObject+DataStore+DataStoreEntry[], Elements: 1)
  39. hash_coll:0x30818946 (System.Int32)
  40. [2] (System.Collections.Hashtable+bucket) VALTYPE (MT=00007ffb79123af8, ADDR=000001ed401e9f88)
  41. key:NULL (System.Object)
  42. val:NULL (System.Object)
  43. hash_coll:0x0 (System.Int32)
  44. increase depth
  45. 0:000> !mdt 000001ed401ea018
  46. 000001ed401ea018 (System.Windows.DataObject+DataStore+DataStoreEntry[], Elements: 1)
  47. expand all 1 items
  48. 0:000> !mdt -e:2 000001ed401ea018
  49. 000001ed401ea018 (System.Windows.DataObject+DataStore+DataStoreEntry[], Elements: 1)
  50. [0] 000001ed401e9ff0 (System.Windows.DataObject+DataStore+DataStoreEntry)
  51. _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 \}}"
  52. _autoConvert:true (System.Boolean)
  53. _aspect:0x1 (System.Runtime.InteropServices.ComTypes.DVASPECT)
  54. _index:0x0 (System.Int32)
  55. increase depth

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

  1. var hostname = System.Net.Dns.GetHostName();
  2. System.Net.IPAddress[] hostaddrs = System.Net.Dns.GetHostAddresses(hostname);
  3. var localIPList = new List<IPAddress>();
  4. for (int i = 0; i < hostaddrs.Length; i++)
  5. {
  6. if (System.Net.Sockets.AddressFamily.InterNetwork == hostaddrs[i].AddressFamily)
  7. {
  8. if (hostaddrs[i].ToString().Equals(_localIP))
  9. {
  10. localIPList.Insert(0, hostaddrs[i]);//优先使用上次连接IP
  11. }
  12. else
  13. {
  14. localIPList.Add(hostaddrs[i]);
  15. }
  16. }
  17. }

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

三:总结

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

图片名称

原文链接:https://www.cnblogs.com/huangxincheng/p/17412584.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号