23

是否有任何内置或第 3 方库可让您在运行时简单地将所有变量转储到内存中?我想要的是能够查看变量和当前值,类似于通过打断点并将鼠标悬停在变量上来查看它们,但实际上不必停止程序执行(即只需获取快照)。如果它可以将它们转储到一个文件中,该文件可以稍后在程序中打开以获得一个漂亮的 GUI 界面来查看它们,那将是很好的,但简单的文本文件转储就足够了。

4

6 回答 6

7

我想不出一种简单的方法来以通用的方式做到这一点。可行的方法是以编程方式创建正在运行的进程的转储文件。您可以使用 P/Invoke 对dbghelp.dll例程执行此操作,或者生成cdb.exe进程来创建转储文件。一旦你有了这个文件,你可以在调试器中打开它,以便以后使用SOS.dll 和 cdb.exe/windbg.exe进行分析,或者甚至编写一个调试器脚本来自动(主要)转储你想要的数据。

于 2009-10-12T03:06:41.433 回答
3

我相信某种日志框架会帮助你做到这一点......

查看:

http://www.dotnetlogging.com/

在我的工作场所,我们使用log4net,它非常适合我们。

那么您为什么要转储所有变量以供以后分析?您是否考虑过先编写代码测试,以便减少对调试器的依赖并拥有一套自动化测试来检查您的值?

于 2009-10-12T03:00:56.797 回答
2

过去,我使用YourKit .Net 分析器来分析 .Net 应用程序。

虽然我个人只使用它连接到正在运行的应用程序,但快照文档确实声明他们有一个Profiler API,可用于以编程方式转储快照以供以后查看。

在代码方面,这看起来很简单,如下所示:

Controller c = new Controller();
String snapshotPath = c.CaptureSnapshot();

我相信您可以稍后将快照文件加载到 YourKit GUI 中以查看它们。

如果其他一些流行的分析器(如 JetBrains dotTrace Performance和 RedGates ANTS Performance Profiler )有类似的编程 API,我不会感到惊讶,但我无法在他们的网站上快速找到明显的文档(而且我不想观看他们的网络研讨会来找到如果这个功能存在!)

于 2012-11-13T00:38:04.310 回答
1

为此,您可以使用WMemoryProfiler

  • 获取所有appdomains中的所有对象作为对象数组
  • 创建自己进程的内存转储
  • 将特定对象序列化到光盘

要实现这一点,您当然需要 Windbg,但 WMemoryProfiler 的 Api 是完全托管的,您基本上可以自行调试您的进程。该库负责处理通常的调试器异常,因为它确实将 Windbg 包装在一个易于访问的库中。

下面的代码确实将 System.Threading.Thread 对象的所有实例放入对象数组中。通过这种方式,您可以在运行时为您自己的应用程序对象编写可视化工具。另一个重载只是为您提供所有 AppDomain 中的所有对象。

using (var debugger = new MdbEng())
{
  var dummy = new Thread(() => {});
  dummy.Name = "Dummy Thread";

  // Get all thread objects in all AppDomains
  var threads = debugger.GetObjects("System.Threading.Thread", true);

  foreach (Thread t in threads)
  {
    Console.WriteLine("Managed thread {0} has Name {1}", t.ManagedThreadId, t.Name);
  }
  GC.KeepAlive(dummy);
}

由于它是 Windbg 的包装器,因此您还可以动态创建内存转储,然后从您的进程中加载​​内存转储,以从转储中提取对象数据以进行可视化。商业内存分析器(例如 Scitech 的 MemoryProfiler)多年来一直采用这种技术,但是当你有一个巨大的内存转储时,它会很慢,因为它们也使用 Windbg 作为转储分析器。

于 2012-11-17T14:49:09.837 回答
0

您可以尝试使用 Visual Studio 终极版提供的Intellitrace工具。这就是您所描述的 - 它记录了您的应用程序中发生的事情,并允许您在不执行程序的情况下调试它,并将鼠标悬停在变量和所有其他调试窗口上以帮助您。

于 2012-11-13T08:43:19.010 回答
0

您可以使用PostSharp。由于部署了环境应用程序,我发现记录调试时间非常有用。并检测/记录了很多东西。

但显然您需要指定所有需要记录的变量。

在此处查看更多详细信息。

于 2012-11-14T16:37:26.600 回答