11

在我之前的问题之后,我想转储堆栈中的所有变量(从当前帧和所有前一帧),可以在这里看到:有没有办法在 C# 中在运行时检查堆栈变量?

有人建议我手动拦截调用或使用 PostSharp 之类的 AOP 框架来简化此类任务。我查看了 PostSharp,拦截参数不包括当前堆栈帧中的变量。我想知道是否有一种简单的方法可以自动获取当前堆栈帧中的所有局部变量。我想我可以执行代码分析并生成将所有这些值复制到集合中的代码,但也许有一个内置机制可以做到这一点。

在此先感谢您的任何建议。

编辑:我应该更详细地说明我为什么要这样做。我希望能够在方法中间暂停执行。如果我有堆栈的内容,我可以稍后恢复执行,甚至可以将其序列化并在另一台机器上继续执行(假设它是相对简单的代码,因此没有线程或 I/O)。可以运行一个代码分析工具,它可以让我自动生成额外的代码来保存这个状态。我想我可能必须分析 CIL 才能做到这一点。

4

3 回答 3

8

您应该使用调试 API 并从另一个进程调试您的程序。编写自己的托管调试器并非易事,但至少是支持实现既定目标的方式。

据我所知,托管 .Net 框架中没有任何内容可用于收集有关方法的局部变量的运行时状态的信息。

请注意,当局部变量的值不存在时,有足够多的情况使编写通用代码来处理它们变得复杂:

  • 方法可以内联(局部变量将与调用方法合并)
  • 局部变量可以优化出来
  • 局部变量可以超出范围并在方法结束之前被垃圾收集。
于 2011-02-27T23:06:10.727 回答
8
   System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace();
        System.Diagnostics.StackFrame frame = trace.GetFrame(0);
        MethodBase method = frame.GetMethod();
        MethodBody methodBody = method.GetMethodBody();
        if (methodBody != null)
        {
            foreach (var local in methodBody.LocalVariables)
            {
                Console.WriteLine(local);
            }
        }
        Console.ReadKey();
于 2011-02-27T21:31:38.993 回答
3

考虑使用自定义 PostSharp 方面(使用 IL 转换)编写小型转储

一个共享的调试引擎库,用 C# 编写。在 NuGet 上以Microsoft.Samples.Debugging.MdbgEngine的形式提供。

该代码作为PADRE(可插入自动调试和报告引擎)存储库的一部分在 GitHub 上提供

于 2012-12-02T03:00:23.287 回答