WinDbg — временная шкала
Отладка временных путешествий (TTD) позволяет пользователям записывать трассировки, которые записывают выполнение программы. Временные шкалы — это визуальное представление событий, происходящих во время выполнения. Эти события могут быть расположениями: точки останова, чтение и запись памяти, вызовы функций и возвраты, а также исключения.
Используйте окно временная шкала, чтобы быстро просмотреть важные события, понять относительное положение и легко перейти к их расположению в файле трассировки TTD. Используйте несколько временная шкала для визуального изучения событий в трассировке путешествия во времени и обнаружения корреляции событий.
Окно временная шкала отображается при открытии файла трассировки TTD и отображает ключевые события без необходимости вручную создавать запросы модели данных. В то же время все объекты перемещения по времени доступны, чтобы обеспечить более сложные запросы данных.
Дополнительные сведения о создании и работе с файлами трассировки временных путешествий см. в разделе "Обзор".
Типы временных шкал
Окно временная шкала может отображать следующие события:
- Исключения (можно дополнительно отфильтровать определенный код исключения)
- Точки останова
- Вызовы функций (поиск в виде модуля!function)
- Доступ к памяти (чтение и запись и выполнение между двумя адресами памяти)
Наведите указатель мыши на каждое событие, чтобы получить дополнительные сведения с помощью подсказки. Щелкнув событие, запустите запрос к событию и отобразите дополнительные сведения. Дважды щелкнув событие, перейдет в это расположение в файле трассировки TTD.
Исключения
При загрузке файла трассировки и активной временная шкала он будет отображать все исключения в записи автоматически.
При наведении указателя мыши на сведения о точке останова, например тип исключения и код исключения, отображаются.
Можно дополнительно отфильтровать определенный код исключения с помощью необязательного поля кода исключения.
Вы также можете добавить новый временная шкала для определенного типа исключения.
Точки останова
После добавления точки останова можно отобразить позиции, когда эта точка останова попадает на временная шкала. Это можно сделать, например, с помощью команды bp Set Breakpoint. При наведении указателя мыши на точку останова отображается адрес и указатель инструкции, связанный с точкой останова.
После очистки точки останова связанная точка останова временная шкала автоматически удаляется.
Вызовы функций
Позиции вызовов функций можно отобразить на временная шкала. Для этого выполните поиск в виде module!function
, например TimelineTestCode!multiplyTwo
. Можно также указать дикие карта, напримерTimelineTestCode!m*
.
При наведении указателя мыши на функцию вызывается имя функции, входные параметры, их значения и возвращаемое значение отображаются. В этом примере показан буфер и размер , так как они являются параметрами DisplayGreeting! GetCppConGreeting.
Доступ к памяти
Используйте временная шкала доступа к памяти, чтобы отобразить, когда определенный диапазон памяти был считыван или записан в, или где выполняется выполнение кода. Адрес запуска и остановки используется для определения диапазона между двумя адресами памяти.
При наведении указателя мыши на элемент доступа к памяти отображается значение и указатель инструкции.
Работа с временная шкала
Вертикальная серая линия следует курсору при наведении указателя мыши на временная шкала. Вертикальная синяя линия указывает текущую позицию трассировки.
Щелкните значок с увеличением масштаба и увеличения масштаба временная шкала.
В верхней временная шкала области управления используйте прямоугольник для сдвига представления временная шкала. Перетащите внешние разделители прямоугольника, чтобы изменить размер текущего временная шкала представления.
Движения мыши
Увеличьте масштаб с помощью ctrl+ Scroll wheel.
Сдвиг от стороны к стороне с помощью shift + Прокрутка колесика.
Методы отладки временной шкалы
Чтобы продемонстрировать методы отладки временная шкала, пошаговое руководство по отладке по времени используется повторно. В этой демонстрации предполагается, что вы выполнили первые два шага по созданию примера кода и созданию записи TTD с помощью первых двух описанных здесь шагов.
Раздел 1. Создание примера кода
Раздел 2. Запись трассировки примера DisplayGreeting
В этом сценарии первым шагом является поиск исключения в трассировке перемещения по времени. Это можно сделать, дважды щелкнув единственное исключение, которое находится на временная шкала.
В командном окне отображается следующая команда, когда мы щелкнули исключение.
(2dcc.6600): Break instruction exception - code 80000003 (first/second chance not available)
Time Travel Position: CC:0
@$curprocess.TTD.Events.Where(t => t.Type == "Exception")[0x0].Position.SeekTo()
Выберите "Просмотр>>регистров", чтобы отобразить регистры на этом этапе в временная шкала, чтобы начать исследование.
В выходных данных команды обратите внимание, что стек (esp) и базовый указатель (ebp) указывают на два очень разных адреса. Это может указывать на повреждение стека, возможно, возвращенную функцию, а затем поврежденную стек. Чтобы проверить это, необходимо вернуться к состоянию ЦП и узнать, можно ли определить, когда произошла ошибка стека.
По мере этого мы рассмотрим значения локальных переменных и стека.
Выберите "Просмотреть>>локальные" для отображения локальных значений.
Выберите "Вид стека">>, чтобы отобразить стек выполнения кода.
В точке сбоя трассировки обычно выполняется несколько шагов после истинной причины обработки ошибок. С путешествием по времени мы можем вернуть инструкцию за раз, чтобы найти истинную первопричину.
На ленте "Главная" используйте команду "Шаг назад" для выполнения трех инструкций. По мере этого продолжайте изучать стек, локальные и регистрировать окна.
В командном окне будут отображаться позиции перемещения по времени и регистры при шаге назад три инструкции.
0:000> t-
Time Travel Position: CB:41
eax=00000000 ebx=00564000 ecx=c0d21d62 edx=7a1e4a6c esi=00061299 edi=00061299
eip=00540020 esp=003cf7d0 ebp=00520055 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
00540020 ?? ???
0:000> t-
Time Travel Position: CB:40
eax=00000000 ebx=00564000 ecx=c0d21d62 edx=7a1e4a6c esi=00061299 edi=00061299
eip=00061767 esp=003cf7cc ebp=00520055 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
DisplayGreeting!main+0x57:
00061767 c3 ret
0:000> t-
Time Travel Position: CB:3A
eax=0000004c ebx=00564000 ecx=c0d21d62 edx=7a1e4a6c esi=00061299 edi=00061299
eip=0006175f esp=003cf718 ebp=003cf7c8 iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
DisplayGreeting!main+0x4f:
0006175f 33c0 xor eax,eax
На этом этапе трассировки наш стек и базовый указатель имеют значения, которые имеют больше смысла, поэтому, по-видимому, мы приближаемся к точке в коде, где произошла коррупция.
esp=003cf718 ebp=003cf7c8
Кроме того, в окне локальных параметров содержатся значения из целевого приложения, а окно исходного кода выделяет строку кода, готовую к выполнению в исходном коде на этом этапе трассировки.
Для дальнейшего изучения можно открыть окно памяти, чтобы просмотреть содержимое рядом с адресом памяти указателя стека (esp). В этом примере имеется значение 003cf7c8. Выберите ASCII текста памяти>>>>, чтобы отобразить текст ASCII, хранящийся на этом адресе.
Доступ к памяти временная шкала
После определения расположения памяти, интересующего вас, добавьте временная шкала доступа к памяти, используя это значение. Нажмите кнопку +Добавить временная шкала и введите начальный адрес. Мы рассмотрим 4 байта, чтобы добавить его в начальный адрес 003cf7c8, у нас есть 003cf7cb. По умолчанию можно просмотреть все операции записи в памяти, но вы также можете посмотреть только на записи или выполнение кода на этом адресе.
Теперь мы можем пройти временная шкала в обратном направлении, чтобы изучить, в какой момент в этом времени трассировка путешествия эта память была записана, чтобы увидеть, что мы можем найти. Щелкнув эту позицию в временная шкала мы видим, что локальные значения отличаются значениями для копируемой строки. Конечное значение, как представляется, не завершено, как если бы длина строки не была правильной.
Временная шкала точки останова
Использование точек останова — это распространенный подход для приостановки выполнения кода на каком-то событии, интересующем вас. TTD позволяет задать точку останова и вернуться назад до тех пор, пока эта точка останова не будет достигнута после записи трассировки. Возможность проверить состояние процесса после того, как возникла проблема, чтобы определить оптимальное расположение точки останова, позволяет дополнительным рабочим процессам отладки, уникальным для TTD.
Чтобы изучить альтернативный метод отладки временная шкала, щелкните исключение в временная шкала и еще раз выполните три шага назад, используя команду "Шаг назад" на ленте "Главная".
В этом очень маленьком примере было бы довольно легко просто выглядеть в коде, но если есть сотни строк кода и десятки вложенных шаблонов, описанные здесь, можно использовать для уменьшения времени, необходимого для поиска проблемы.
Как упоминание ранее, базовый указатель (esp) вместо указания инструкции указывает на текст сообщения.
Используйте команду ba, чтобы задать точку останова для доступа к памяти. Мы установим точку останова записи, чтобы узнать, когда эта область памяти записывается в.
0:000> ba w4 003cf7c8
Хотя мы будем использовать простую точку останова доступа к памяти, точки останова можно создать, чтобы быть более сложными условными операторами. Дополнительные сведения см. в разделе bp, bu, bm (Set Breakpoint).
В меню "Главная" выберите "Вернуться назад", пока точка останова не будет достигнута.
На этом этапе мы можем проверить стек программ, чтобы узнать, какой код активен.
Так как маловероятно, что у предоставленной корпорацией Майкрософт функции wscpy_s() будет ошибка кода, как в этом случае, мы ищем дополнительные сведения в стеке. В стеке показано, что приветствие!main вызывает Приветствие! GetCppConGreeting. В нашем очень маленьком примере кода мы могли просто открыть код на этом этапе и, скорее всего, найти ошибку довольно легко. Но чтобы проиллюстрировать методы, которые можно использовать с более крупной, более сложной программой, мы добавим вызов функции временная шкала.
Вызов функции временная шкала
Нажмите кнопку +Добавить временная шкала и заполните DisplayGreeting!GetCppConGreeting
строку поиска функции.
Поле "Начальное и конечное" проверка указывает, что начало и конец вызова функции в трассировке.
Мы можем использовать команду dx для отображения объекта вызова функции, чтобы просмотреть связанные поля TimeStart и TimeEnd, соответствующие начальному расположению и конечному расположению вызова функции.
dx @$cursession.TTD.Calls("DisplayGreeting!GetCppConGreeting")[0x0]
EventType : 0x0
ThreadId : 0x6600
UniqueThreadId : 0x2
TimeStart : 6D:BD [Time Travel]
SystemTimeStart : Thursday, October 31, 2019 23:36:05
TimeEnd : 6D:742 [Time Travel]
SystemTimeEnd : Thursday, October 31, 2019 23:36:05
Function : DisplayGreeting!GetCppConGreeting
FunctionAddress : 0x615a0
ReturnAddress : 0x61746
Parameters
Поля "Начало" или "Конец" или "Начало" и "Конец" должны быть проверка.
Так как наш код не является рекурсивным или повторным записью, это довольно легко найти в строке времени при вызове метода GetCppConGreeting. Вызов GetCppConGreeting также происходит в то же время, как наша точка останова, а также событие доступа к памяти, которое мы определили. Так что похоже, что мы сузились в области кода, чтобы внимательно изучить первопричину сбоя приложения.
Изучение выполнения кода путем просмотра нескольких временная шкала
Хотя наш пример кода мал, метод использования нескольких временная шкала позволяет визуально исследовать трассировку перемещения по времени. Вы можете просмотреть файл трассировки, чтобы задать вопросы, такие как "когда область памяти, доступ к ней осуществляется до попадания точки останова?".
Возможность просматривать дополнительные корреляции и находить ожидаемые вещи, может отличать средство временная шкала от взаимодействия с трассировкой перемещения по времени с помощью команд командной строки.
Закладки временной шкалы
Закладка важных позиций поездок по времени в WinDbg вместо ручного копирования позиции в блокнот. Закладки упрощают просмотр разных позиций трассировки относительно других событий и их анимацию.
Вы можете указать описательное имя для закладок.
Доступ к закладкам через окно временной шкалы, доступное в режиме просмотра > временной шкалы. При наведении указателя мыши на закладку будет отображаться имя закладки.
Щелкните правой кнопкой мыши закладку, чтобы перейти к этой позиции, переименовать или удалить закладку.
Примечание.
В версии 1.2402.24001.0 отладчика функция закладки недоступна.