Как получить трассировку стека запущенного процесса из надстройки Visual Studio?

Я пишу надстройку Visual Studio на С#, которая будет работать, пока я отлаживаю процесс в том же окне Visual Studio, и мне нужен доступ к трассировке стека этого процесса из моей надстройки. Я попытался поместить этот код в свою надстройку, но он возвращает трассировку стека надстройки, а не отлаживаемый процесс.

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

Любая помощь будет оценена по достоинству.


person Jack    schedule 01.06.2010    source источник


Ответы (2)


Самый простой способ — запросить у отладчика кадры стека через объект автоматизации 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();
    }

Болезненный и сложный способ — использовать ICorDebug и StackWalk64, чтобы отдельно получить управляемые и собственные стеки, а затем объединить их. вместе вручную. Поскольку вы являетесь надстройкой VS, вы можете позволить отладчику сделать всю тяжелую работу за вас!

person Chris Schmich    schedule 02.06.2010
comment
Большое спасибо за ответ! Я обязательно попробую. - person Jack; 03.06.2010
comment
Есть ли шанс, что вы знаете, как получить номера строк и/или сигнатуры функций? - person Earlz; 10.01.2013
comment
Неважно, разобрался (но это некрасиво), см. stackoverflow.com/a/14251675/69742 - person Earlz; 10.01.2013
comment
См. go4answers.webhost4life.com/Example/. По сути, вы можете вызвать DTE.Debugger.GetExpression для оценки выражений через отладчик. Это может помочь вам получить информацию об исключении. - person Chris Schmich; 07.12.2013

Код работает, как и ожидалось, поскольку при вызове кода ваша надстройка (в VS) является «текущим процессом».

Я не уверен, что вы подразумеваете под «текущим процессом» (вы имеете в виду процесс, который запускается/отлаживается в VS?), но я не думаю, что возможно получить трассировку стека другого процесса.

person logicnp    schedule 02.06.2010
comment
Да, у меня надстройка запускается в Visual Studio, пока я отлаживаю процесс в том же окне Visual Studio, и мне нужен доступ к трассировке стека этого процесса внутри моей надстройки. - person Jack; 02.06.2010