Как получить значение параметров в stacktrace

Я могу получить информацию о параметре StackTrace, используя что-то вроде этого:

catch (Exception ex)
{
    var st = new StackTrace(ex);

    System.Reflection.ParameterInfo pi = st.GetFrame(0).GetMethod().GetParameters().First();
}

Я хочу знать, как получить значение параметра. Пример:

Если мой метод в трассировке стека был следующим:

void MyMethod(object value)

И вызов был следующим:

MyMethod(10);

Я хочу получить значение 10. Как я это делаю?

Ответ 1

Есть два пути. Более мощным является COM API для отладки .NET. Например, аргументы и локальные переменные функции в стеке вызовов доступны из ICorDebugILFrame. Но это должно запускаться из отдельного процесса, который прилагается к вашему процессу в качестве отладчика.

Для интроспекции in-process существует Profiler API, который также может найти информацию о аргументах функций. Посмотрите на информацию о "теневых стеках".

Ответ 2

Не с С#, кроме случаев, когда вы создаете решение, зависящее от версии CLR (patch). Но что нужно сделать, чтобы подключить Windbg к вашему процессу, загрузите sos.dll в свой поток и введите

!ClrStack -p

для отображения стека управляемых вызовов и параметров метода для большинства методов. Это даже под отладчиком не является надежным, потому что из-за встроенных и JIT-оптимизаций макет стека очень гибкий. Кроме того, некоторые параметры могут даже не отображаться в памяти стека, поскольку они передаются через регистры (что еще более распространено в платформе x64).

Чтобы ответить на ваш первый вопрос. Нет, это невозможно с помощью подхода, который вы пытаетесь сделать. Рабочее решение будет возможно, но не совсем переносимым. Управляемый отладчик может частично извлекать ваши аргументы, но нет 100% рабочего решения (даже под отладчиком).