是否有任何内置或第 3 方库可让您在运行时简单地将所有变量转储到内存中?我想要的是能够查看变量和当前值,类似于通过打断点并将鼠标悬停在变量上来查看它们,但实际上不必停止程序执行(即只需获取快照)。如果它可以将它们转储到一个文件中,该文件可以稍后在程序中打开以获得一个漂亮的 GUI 界面来查看它们,那将是很好的,但简单的文本文件转储就足够了。
6 回答
我想不出一种简单的方法来以通用的方式做到这一点。可行的方法是以编程方式创建正在运行的进程的转储文件。您可以使用 P/Invoke 对dbghelp.dll例程执行此操作,或者生成cdb.exe进程来创建转储文件。一旦你有了这个文件,你可以在调试器中打开它,以便以后使用SOS.dll 和 cdb.exe/windbg.exe进行分析,或者甚至编写一个调试器脚本来自动(主要)转储你想要的数据。
我相信某种日志框架会帮助你做到这一点......
查看:
在我的工作场所,我们使用log4net,它非常适合我们。
那么您为什么要转储所有变量以供以后分析?您是否考虑过先编写代码测试,以便减少对调试器的依赖并拥有一套自动化测试来检查您的值?
过去,我使用YourKit .Net 分析器来分析 .Net 应用程序。
虽然我个人只使用它连接到正在运行的应用程序,但快照文档确实声明他们有一个Profiler API,可用于以编程方式转储快照以供以后查看。
在代码方面,这看起来很简单,如下所示:
Controller c = new Controller();
String snapshotPath = c.CaptureSnapshot();
我相信您可以稍后将快照文件加载到 YourKit GUI 中以查看它们。
如果其他一些流行的分析器(如 JetBrains dotTrace Performance和 RedGates ANTS Performance Profiler )有类似的编程 API,我不会感到惊讶,但我无法在他们的网站上快速找到明显的文档(而且我不想观看他们的网络研讨会来找到如果这个功能存在!)
为此,您可以使用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 作为转储分析器。
您可以尝试使用 Visual Studio 终极版提供的Intellitrace工具。这就是您所描述的 - 它记录了您的应用程序中发生的事情,并允许您在不执行程序的情况下调试它,并将鼠标悬停在变量和所有其他调试窗口上以帮助您。