如何在代码分析器中运行C#app与运行一个外部代码分析器有什么不同?

时间:2012-08-23 16:06:28

标签: c# .net profiler

我试图了解代码分析器(在本例中为Drone Profiler)如何运行.NET应用程序与直接运行它不同。我需要知道这个的原因是因为我的开发计算机的.NET安装有一个非常奇怪的问题/腐败,它在分析器之外表现出来但很奇怪不在里面,如果我能理解为什么我可以解决我的计算机问题。

这个问题似乎只会影响对System.Net.NetworkInformation方法的调用(并且只在.NET 3.5到2.0中,如果我构建一个针对4的东西,那么很好)。我构建了一个小测试应用程序,它只做一件事,它调用System.Net.NetworkInformation.IsNetworkAvailable()。在分析器之外,我在System.dll中发生了“致命执行引擎错误”,这就是它提供的所有信息。据我所知,错误通常是由本机方法调用引起的,当System.dll允许某些本机DLL执行IsNetworkAvailable()逻辑时,可能会发生错误。

  • 我尝试使用Process Monitor找出探查器差异的内部和外部,记录两种情况下的事件并进行比较。两个日志都是相同的,直到iphlpapi.dll和winnsi.dll被调用之后,在探测器运行代码dnsapi.dll和非探查器代码开始加载崩溃报告相关的东西之前。在那个似乎出错的时刻,探查器运行的代码创建了4-6个新线程,而非探查器(崩溃)代码只创建了1或2.我不知道这意味着什么,如果有的话。

可以说是不必要的背景

我的Windows 7包括.NET安装(3.5到2.0)工作正常,直到我的硬盘遭遇一些损坏并且checkdisk开始找到坏群集。我将驱动器映像到一个新的驱动器,一切正常,除了.NET的这个问题。

我需要解决此问题,重新安装Windows或恢复映像备份。

以下是我所研究的一些事项:

  • 我已经把磁盘前后麻烦的文件/目录看起来最相关(Windows和程序文件下的.NET内容),看不到任何我没想到的变化(没有明显的文件损坏)。
  • 我已经在软件和系统注册表中分析了磁盘前后的麻烦,并且没有看到任何相似的变化。
  • 我创建了一个新的用户帐户,并在环境相关的情况下清理了所有环境变量。没有变化。
  • 我做了“sfc / scannow”,发现没有完整性问题。
  • 我尝试了“ngen update”来重新生成预编译的代码,以防我遗漏了可能已损坏且没有任何变化的内容。
  • 我删除了我的病毒扫描程序,看它是否有干扰,没有区别。
  • 我尝试在安全模式下运行测试代码,同样是崩溃问题。

我认为我需要修复我的.NET安装,但由于Windows 7包含.NET 3.5 - 2.0,因此您无法重新运行.NET安装程序来重做它。我无法访问Windows磁盘以尝试重新安装Windows(计算机有一个恢复分区,但它无法使用);此外,该驱动器使用整盘加密解决方案,重新安装将很困难。

我绝对不想从头开始安装新的Windows,重新安装几十个软件包,尝试并记住几十个与开发相关的自定义/等。

鉴于这一切......有没有人有任何有用的建议?我需要.NET 3.5 - 2.0,因为我是一名开发人员,需要构建并测试它。

谢谢!

Quinxy

2 个答案:

答案 0 :(得分:1)

简短的回答是我的System.ni.dll文件已损坏,我更换了它,一切都很好。

长期答案可能会通过其解决方案的方式帮助其他人......

我的问题与.Net被破坏有关,除非通过分析器,否则应用程序无法运行。我下载了SlimTune open source profiler的源代码,在本地构建它,并在调用Process.Start()之前设置了一个断点。然后,我通过分析器与手动比较了成功启动应用程序所涉及的所有参数。我发现唯一有意义的区别是添加了添加到环境变量的.NET配置文件参数:

  • cor_enable_profiling = 1
  • COR_PROFILER = {38A7EA35-B221-425a-AD07-D058C581611D}

然后我尝试在我自己的用户环境中设置这些,瞧!现在我手动运行的任何应用程序都可以。 (我实际上已经尝试过几个小时前做同样的事情,但我使用的GUID包含在一个示例中,并没有指向一个真正的探查器,显然.NET知道我给它一个虚假的GUID并没有以分析模式运行。)

我现在回过头来开始阅读CLR如何执行PE文件,希望弄清楚为什么我的应用程序在启用了性能分析的情况下运行起来很重要。我学到了很多,但似乎并没有什么适用。

但我记得我应该重新检查chkdsk日志,我一直列出驱动器故障损坏的文件。失败之后我将所有列出的文件ID转换为文件路径/名称,我已经从备份中替换了所有100多个文件,但是当我现在回去看看时我确实发现了一条说明,当我更换4或5个.NET相关文件成功有一个这样的文件我无法替换,因为它“正在使用”。那档案? System.ni.dll!我现在能够从备份中替换此文件,并且我的.NET安装恢复正常,无论是否已分析,应用程序都能正常工作。

令人沮丧的是,当这个事件第一次发生时,我完全预料到问题与损坏的文件有关,特别是与一个名为System.dll的文件有关,该文件包含失败的方法。所以我对所有名为System.dll的文件进行了差异化处理。但我当时没有意识到System.ni.dll是System.dll(或某些)的本机编译表现形式。而且因为我对.NET相关目录进行了差异化并且没有注意到这一点(不知道我是如何错过的)我已经放弃了这种方法。

无论如何......长话短说,这是一个损坏的System.ni.dll导致我的问题,其中的一个或多个集群的内容被替换为0x0,它恰好表现为我观察到的奇怪问题

答案 1 :(得分:0)

这听起来像是一个时间问题,分析器通过使其稍微慢一些来“修复”。

许多分析器使用检测(more info here),这会稍微降低应用程序的速度。显然它会减慢一个线程的速度,使另一个线程可以做更多的工作,防止崩溃。像这样的错误通常不直接在开发人员机器上表现出来,而是在具有更多内核或超线程的处理器上运行时立即出现。有时它们只出现在发布版本中(反之亦然,在调试版本中)。时序问题可能难以追踪,因为相同的代码可能在不同的条件下(在分析器或调试器中)给出不同的结果。

根据您的描述,我将尝试对如何修复它进行疯狂猜测:

尝试在源中查找新线程的启动位置。然后在它们产生之后在那里添加System.Threading.Thread.Sleep(500);行来暂停主线程并给新线程一些时间来启动。

如果没有源代码和崩溃的一些堆栈跟踪,这是相当多的猜测。