VS2010Datatable查看器查看超时(Microsoft.VisualStudio.DebuggerVisualizers)

这个问题由来已久,却一直没有找到原因。大家都知道,VisualStudio的DebuggerVisualizers是一个非常方便的插件,可以帮助我们调试时查看Datatable视图,前阵子突然发现在查看时报错了,截图 如下:

\

  详细信息里的内容是:


加载中...
01. 1 有关调用实时(JIT)调试而不是此对话框的详细信息,
02. 2 请参见此消息的结尾。
03. 3
04. 4 ************** 异常文本 **************
05. 5 System.Exception: 函数计算超时。
06. 6    在 Microsoft.VisualStudio.DebuggerVisualizers.DebugViewerShim.PrivateCallback.MaybeDeserializeAndThrowException(Byte[] data)
07. 7    在 Microsoft.VisualStudio.DebuggerVisualizers.DebugViewerShim.ManagedShim.DelegatedHost.CreateViewer(IntPtr hwnd, HostServicesHelper hsh, SafeProxyWrapper proxy)
08. 8
09. 9
10. 10 ************** 已加载的程序集 **************
11. 11 mscorlib
12. 12     程序集版本:4.0.0.0
13. 13     <a href="http://www.it165.net/pro/" target="_blank" class="keylink">Win32</a> 版本:4.0.30319.18444 built by: FX451RTMGDR
14. 14     基本代码:file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/mscorlib.dll
15. 15 ----------------------------------------
16. 16 Microsoft.VisualStudio.Platform.AppDomainManager
17. 17     程序集版本:12.0.0.0
18. 18     <a href="http://www.it165.net/pro/" target="_blank" class="keylink">Win32</a> 版本:12.0.21005.1
19. 19     基本代码:file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/Microsoft.VisualStudio.Platform.AppDomainManager/v4.0_12.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualStudio.Platform.AppDomainManager.dll
20. 20 ----------------------------------------
21. 21 System
22. 22     程序集版本:4.0.0.0
23. 23     Win32 版本:4.0.30319.18408 built by: FX451RTMGREL
24. 24     基本代码:file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll
25. 25 ----------------------------------------
26. 26 System.Configuration
27. 27     程序集版本:4.0.0.0
28. 28     Win32 版本:4.0.30319.18408 built by: FX451RTMGREL
29. 29     基本代码:file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Configuration/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
30. 30 ----------------------------------------
31. 31 System.Xml
32. 32     程序集版本:4.0.0.0
33. 33     Win32 版本:4.0.30319.34234 built by: FX452RTMGDR
34. 34     基本代码:file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Xml/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.dll
35. 35 ----------------------------------------
36. 36 System.Windows.Forms
37. 37     程序集版本:4.0.0.0
38. 38     Win32 版本:4.0.30319.18408 built by: FX451RTMGREL
39. 39     基本代码:file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
40. 40 ----------------------------------------
41. 41 System.Drawing
42. 42     程序集版本:4.0.0.0
43. 43     Win32 版本:4.0.30319.18408 built by: FX451RTMGREL
44. 44     基本代码:file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
45. 45 ----------------------------------------
46. 46 Microsoft.VisualStudio.DebuggerVisualizers
47. 47     程序集版本:12.0.0.0
48. 48     Win32 版本:12.0.21005.1
49. 49     基本代码:file:///C:/Windows/assembly/GAC_MSIL/Microsoft.VisualStudio.DebuggerVisualizers/12.0.0.0__b03f5f7f11d50a3a/Microsoft.VisualStudio.DebuggerVisualizers.dll
50. 50 ----------------------------------------
51. 51 System.Windows.Forms.resources
52. 52     程序集版本:4.0.0.0
53. 53     Win32 版本:4.0.30319.18408 built by: FX451RTMGREL
54. 54     基本代码:file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms.resources/v4.0_4.0.0.0_zh-Hans_b77a5c561934e089/System.Windows.Forms.resources.dll
55. 55 ----------------------------------------
56. 56
57. 57 ************** JIT 调试 **************
58. 58 要启用实时(JIT)调试,
59. 59 该应用程序或计算机的 .config 文件(machine.config)的 system.windows.forms 节中必须设置
60. 60 jitDebugging 值。
61. 61 编译应用程序时还必须启用
62. 62 调试。
63. 63
64. 64 例如:
65. 65
66. 66 <configuration>
67. 67     <system.windows.forms jitDebugging='true' />
68. 68 </configuration>
69. 69
70. 70 启用 JIT 调试后,任何未经处理的异常
71. 71 都将被发送到在此计算机上注册的 JIT 调试器,
72. 72 而不是由此对话框处理。

  从这个错误内容来看,最后抛出的是行6和行7,这是IDE绘制查看器弹窗时抛出的异常,我找了下这个dll,还真找到了,具体位置在

1. Common7IDEReferenceAssemblies 2.0Microsoft.VisualStudio.DebuggerVisualizers.dll

  当然,VS真正调的应该不是这个位置,从错误行49可以看出(实际上把这个位置的DebuggerVisualizers.dll删除照样可以使用),是调的Windows下面的某个位置,这可能是写到注册表里或者环境变量里了,反正是这个dll不错,但是vs使用的位置我没法查到。用Reflector反编译之,行7的CreateViewer源码如下:


加载中...
01. 1 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine), ResourceExposure(ResourceScope.None)]
02. 2 internal void CreateViewer(IntPtr hwnd, ManagedShim.HostServicesHelper hsh, ManagedShim.SafeProxyWrapper proxy)
03. 3 {
04. 4     try
05. 5     {
06. 6         byte[] data = proxy.InitSourceDataProvider();
07. 7         using (AssemblyResolver resolver = new HostResolver(proxy, hsh.IsRemote, new ServiceProvider.WindowWrapper(hwnd)))
08. 8         {
09. 9             string str;
10. 10             string str2;
11. 11             int num;
12. 12             ASSEMBLYLOCRESOLUTION assemblylocresolution;
13. 13             byte[] buffer;
14. 14             byte[] buffer2;
15. 15             PrivateCallback.MaybeDeserializeAndThrowException(data);
16. 16             proxy.GetManagedViewerCreationData(out str, out buffer, out buffer2, out str2, out assemblylocresolution, out num);
17. 17             if ((assemblylocresolution == ASSEMBLYLOCRESOLUTION.ALR_ERROR) && (str != null))
18. 18             {
19. 19                 throw new TerminalException(str, MessageBoxIcon.Hand);
20. 20             }
21. 21             if (((buffer != null) && (str == null)) && (hsh.IsRemote && !QueryRemoteLoadAllowed(nullnew ServiceProvider.WindowWrapper(hwnd))))
22. 22             {
23. 23                 throw new TerminalException(MessageBoxIcon.Hand);
24. 24             }
25. 25             ClassAndAssemblySpec spec = new ClassAndAssemblySpec(str, buffer, assemblylocresolution != ASSEMBLYLOCRESOLUTION.ALR_NAME, str2);
26. 26             DialogDebuggerVisualizer visualizer = (DialogDebuggerVisualizer) spec.CreateInstance(resolver);
27. 27             using (PrivateCallback callback = new PrivateCallback(proxy, num != 0))
28. 28             {
29. 29                 visualizer.Show(new ServiceProvider(hwnd, hsh).DialogService, callback);
30. 30             }
31. 31         }
32. 32     }
33. 33     catch (TerminalException exception)
34. 34     {
35. 35         exception.DisplayDialog(new ServiceProvider.WindowWrapper(hwnd));
36. 36     }
37. 37     catch (Exception exception2)
38. 38     {
39. 39         new ThreadExceptionDialog(exception2).ShowDialog(new ServiceProvider.WindowWrapper(hwnd));
40. 40     }
41. 41 }

  从上面可以看出,走到行15就执行了异常处理,然后由PrivateCallback的MaybeDeserializeAndThrowException方法接管过来,MaybeDeserializeAndThrowException源码如下:


加载中...
01. 1 internal static unsafe byte[] MaybeDeserializeAndThrowException(byte[] data)
02. 2 {
03. 3     if ((data == null) || (data.Length == 0))
04. 4     {
05. 5         return null;
06. 6     }
07. 7     DebugeeHost.DataPrefix prefix = (DebugeeHost.DataPrefix) data[0];
08. 8     switch (prefix)
09. 9     {
10. 10         case DebugeeHost.DataPrefix.Exception:
11. 11         {
12. 12             Exception exception = (Exception) DeserializeObject(data, 1);
13. 13             throw exception;
14. 14         }
15. 15         case DebugeeHost.DataPrefix.ObjectData:
16. 16             return data;
17. 17
18. 18         case DebugeeHost.DataPrefix.CustomExceptionData:
19. 19         {
20. 20             DebugeeHost.CustomExceptionDataHolder cedh = (DebugeeHost.CustomExceptionDataHolder) DeserializeObject(data, 1);
21. 21             throw new RemoteObjectSourceException(cedh);
22. 22         }
23. 23         case DebugeeHost.DataPrefix.ErrorString:
24. 24         case DebugeeHost.DataPrefix.ErrorStringNoHost:
25. 25             if (data.Length < 8)
26. 26             {
27. 27                 throw new ApplicationException(SR.GetString('E_G_InvalidSerializationFormat'));
28. 28             }
29. 29             break;
30. 30
31. 31         default:
32. 32             return data;
33. 33     }
34. 34     fixed (byte* numRef = data)
35. 35     {
36. 36         int length = numRef[4];
37. 37         if ((data.Length - 8) < (length * 2))
38. 38         {
39. 39             throw new ApplicationException(SR.GetString('E_G_InvalidSerializationFormat'));
40. 40         }
41. 41         char* chPtr = (char*) (numRef + 8);
42. 42         string message = new string(chPtr, 0, length);
43. 43         if (prefix == DebugeeHost.DataPrefix.ErrorStringNoHost)
44. 44         {
45. 45             throw new TerminalException(message, MessageBoxIcon.Exclamation);
46. 46         }
47. 47         throw new Exception(message);
48. 48     }
49. 49 }

  这里应该就是最后的“事发现场了”,其中case的枚举如下:


加载中...
1. 1 internal enum DataPrefix : byte
2. 2 {
3. 3     CustomExceptionData = 3,
4. 4     ErrorString = 4,
5. 5     ErrorStringNoHost = 5,
6. 6     Exception = 1,
7. 7     ObjectData = 2
8. 8 }

  到此好像没法追踪下去了,它是通过传入的byte[]的0位值来抛出相应的异常,只有值为2或者default的时候才不抛出,由于没法模拟环境,即使我给了传入byte[],那么里面的调用层次还是要经过一番考究的。为此我也考虑了其他因素:

系统

硬件

内存

杀毒软件

IDE本身

软件冲突

补丁

IDE配置

  现在的现象是时好时坏,那么2、7就可以排除了,找了另外一台电脑,同样的系统同样的vs版本可以查看,那么1和5可以排除,内存用360释放一样有错,3可以排除,杀毒软件退掉依旧,4可以排除,6的话就麻烦了,难以查证,8的话也对比了正常的配置,没有差异,也可排除。

  现在比较有效的办法是杀进程,在任务管理器里结束与vs项目相关的host进程(不包括devenv.exe),如果有MSBuildTaskHost也要结束,然后再启动新实例,一般都能正常查看。

转载地址:http://www.it165.net/pro/html/201501/30763.html


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值