Как просмотреть локальные переменные в стеке оценки при отладке приложения .NET CLR?

StackOverflow https://stackoverflow.com/questions/522522

Вопрос

Я использую Windbg (с расширением sos) и пытаюсь отладить сбойное приложение.Мне удалось сбросить IL-код вызова, вызвавшего исключение, и, изучив код, кажется, что я мог бы получить необходимую мне информацию, если бы мог сбросить содержимое стека оценки.Можно ли что сделать с WinDbg & sos?

Вот что я сделал:

  1. Запустил WinDbg
  2. Прикреплен к аварийному процессу
  3. загрузка через sos mscorwks (чтобы загрузить расширение SOS)
  4. !token2ee theModuleName 0600009а (где theModuleName Является ли название приложения (и сборки), которую я отлаживаю и — это смещение метода, который произошел сбой, как сообщает инструмент отчетов об ошибках Windows..Я получил этот вывод:

    Модуль:000e2c3c (ИмяПриложения.exe)
    Токен:0x0600009a
    Описание метода:000e67c8
    Имя:MyNamespace.MyClassName.theCulpritFn(MyOtherClass)
    Адрес кода JITTED:0081b1d0

  5. !дампил 00e67c8 (который сбросил IL для рассматриваемого метода).Это результат:

    
    // ..
    // .. the previous code omitted for brevity
    .catch
    {
     IL_0071: stloc.0
     IL_0072: nop
     IL_0073: ldstr "Can't set CurrentServer property for: "
     IL_0078: ldarg.0
     IL_0079: ldfld MyNamespace.MyClassName::_currentServer
     IL_007e: brtrue.s IL_0087
     IL_0080: ldstr ""
     IL_0085: br.s IL_0092
     IL_0087: ldarg.0
     IL_0088: ldfld MyNamespace.MyClassName::_currentServer
     IL_008d: callvirt MyNamespace.MyOtherClass::get_Name
     IL_0092: call System.String::Concat
     IL_0097: ldloc.0
     IL_0098: newobj MyNamespace.MySpecialExceptionType::ctor
     IL_009d: throw
    } 
    

    Вопрос в том:Есть ли у меня способ увидеть, что было помещено в стек до того, как было выбрано исключение.Если я не ошибаюсь, аргумент, передаваемый в конструктор исключений, должен быть локальной переменной с индексом 0 в стеке вычислений.

    P.S.Когда я пытался позвонить !clrstack -а Мне пришло сообщение:Невозможно пройти по управляемому стеку.Текущий поток, скорее всего, не является управляемым потоком.Вы можете запустить !threads, чтобы получить список управляемых потоков в процессе.

Спасибо!

Это было полезно?

Решение

Вам необходимо определить и выбрать нужную нить.Идентификатор текущего потока отображается в командной строке WinDbg.

!threads отобразит все управляемые потоки в вашем приложении.После идентификации вы можете переключать потоки, используя ~Xs где X — идентификатор WinDbg для потока.

!clrstack покажет вам трассировку стека.Если вы хотите, чтобы локальные жители и/или параметры использовали -l / -p (или -a для обоих).

Вы можете просмотреть все потоки и перечислить их стек вызовов с помощью ~*e!clrstack.

Если local/parameters не дает вам того, что вам нужно, используйте !dso для отображения объектов, помещенных в стек.

Другие советы

Ух ты, как это сложно без настоящего дампа, через который можно пролезть.:-)

Вот пару вопросов..а затем я добавлю одну команду, которая ранее не была указана в ответах выше..

Вопросы:

  1. Вы уверены, что перехватываете первое исключение, а не только последнее, которое не было обработано и прервало процесс?

  2. Можете ли вы взглянуть на собственный стек вызовов потока, вызвавшего исключение?
    Примечание:должен быть вызов RaiseException() или нарушение прав доступа.

  3. Остерегайтесь асинхронных исключений, которые не имеют абсолютно никакого отношения к вашему коду и могут попасть в блок catch...или хуже (Thread.AbortException/System.OutofMemoryException и...StackOverflowException :-)

Чтобы копнуть дальше, вы бежите !свалка в неисправной ветке..Результат: не точный однако он делает потрясающую работу по обходу стека вызовов потоков, и вам может повезти, и вы увидите @ символ, который ссылается на исключение с расширением .cxr и .exr в сообщении.Если да, то можешь бежать .cxr -cxr-адрес и посмотреть, какое исключение было первым в цепочке исключений.

Точка:Хотя я, возможно, уклоняюсь от ответа на этот вопрос, но если исключение вызвало WER, то это было не обработано и удалили процесс, который вы, возможно, захотите зарегистрировать в исходном стеке вызовов или добавить предыдущее исключение в качестве внутреннего исключения, чтобы вы могли определить основную причину.

Спасибо, Аарон

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top