【问题标题】:How to get stack trace of a running process from within a Visual Studio add-in?如何从 Visual Studio 加载项中获取正在运行的进程的堆栈跟踪?
【发布时间】:2010-06-01 23:34:20
【问题描述】:

我正在用 C# 编写一个 Visual Studio 加载项,当我在同一个 Visual Studio 窗口中调试进程时将运行该加载项,我需要从加载项中访问该进程的堆栈跟踪。我尝试将此代码放入我的加载项,但它返回加载项的堆栈跟踪,而不是我正在调试的进程。

System.Diagnostics.StackTrace stacktrace = new System.Diagnostics.StackTrace(true);
System.Diagnostics.StackFrame stackframe = stacktrace.GetFrame(0);

任何帮助将不胜感激。

【问题讨论】:

    标签: c# visual-studio add-in stack-trace


    【解决方案1】:

    最简单的方法是通过DTE 自动化对象向调试器询问堆栈帧。 DTE 对象应该可以通过您的加载项使用。你想要的属性是Debugger.CurrentThread.StackFrames。如果您使用的是 .NET 4,您可以这样做:

        static string GetCurrentStackTrace(DTE dte)
        {
            bool canGetStackTrace =
                (dte != null) &&
                (dte.Debugger != null) &&
                (dte.Debugger.CurrentThread != null) &&
                (dte.Debugger.CurrentThread.StackFrames != null);
    
            if (!canGetStackTrace)
                return string.Empty;
    
            return string.Join(
                "\n",
                dte.Debugger.CurrentThread.StackFrames.Cast<StackFrame>().Select(f => f.FunctionName)
            );
        }
    

    否则,你可以这样做:

        static string GetCurrentStackTrace(DTE dte)
        {
            bool canGetStackTrace =
                (dte != null) &&
                (dte.Debugger != null) &&
                (dte.Debugger.CurrentThread != null) &&
                (dte.Debugger.CurrentThread.StackFrames != null);
    
            if (!canGetStackTrace)
                return string.Empty;
    
            StringBuilder stackTrace = new StringBuilder();
    
            foreach (StackFrame frame in dte.Debugger.CurrentThread.StackFrames)
            {
                stackTrace.AppendFormat("{0}\n", frame.FunctionName);
            }
    
            return stackTrace.ToString();
        }
    

    痛苦而复杂的方法是使用ICorDebugStackWalk64 分别获取托管堆栈和本机堆栈,然后手动将它们拼接在一起。既然你是 VS 插件,不妨让调试器为你代劳!

    【讨论】:

    【解决方案2】:

    代码按预期工作,因为当您调用代码时,您的加载项(在 VS 下)是“当前进程”。

    我不确定您所说的“当前正在运行的进程”是什么意思(您是指在 VS 下运行/调试的进程吗?),但我认为不可能获得另一个进程的堆栈跟踪。

    【讨论】:

    • 是的,当我在同一个 Visual Studio 窗口中调试进程时,我正在 Visual Studio 中运行加载项,我需要访问加载项内的该进程的堆栈跟踪。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-10
    • 2011-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-31
    相关资源
    最近更新 更多