Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Отладка с временным путешествием (TTD) позволяет пользователям записывать трассировки, фиксирующие выполнение программы. Временные шкалы — это визуальное представление событий, происходящих во время процесса выполнения. Эти события могут быть расположениями точек останова, операций чтения и записи памяти, вызовов функций и возврата, а также исключений.
Используйте окно временной шкалы , чтобы просмотреть важные события, понять их относительное положение и легко перейти к их расположению в файле трассировки TTD. Используйте несколько временных шкал для визуального изучения событий в трассировке перемещения по времени и обнаружения корреляции событий.
Окно временной шкалы отображается при открытии файла трассировки TTD. В нем отображаются ключевые события без необходимости вручную создавать запросы модели данных. В то же время все объекты перемещения по времени доступны, чтобы обеспечить более сложные запросы данных.
Дополнительные сведения о создании и работе с файлами трассировки перемещения по времени см. в разделе "Отладка временных путешествий : обзор".
Типы временных шкал
В окне "Временная шкала" отображаются события в следующих временных шкалах:
- Исключения. Вы можете отфильтровать определенный код исключений.
- Точки останова: можно увидеть, когда точки останова попадают на временную шкалу.
- Доступ к памяти: можно считывать, записывать и выполнять между двумя адресами памяти.
-
Вызовы функций: можно выполнять поиск в виде
module!function.
Наведите указатель мыши на каждое событие, чтобы получить дополнительные сведения с помощью подсказки. При выборе события выполняется запрос события и отображаются дополнительные сведения. Когда пользователь дважды щелкает на событии, файл трассировки TTD переходит в это расположение.
Исключения
При загрузке файла трассировки и при активной временной шкале автоматически отображаются все исключения в записи.
При наведении указателя мыши на точку останова отображаются такие сведения, как тип исключения и код исключения.
Можно дополнительно отфильтровать определенный код исключения с помощью необязательного поля "Код исключения ".
Можно также добавить новую временную шкалу для определенного типа исключения.
Точки останова
После добавления точки останова, позиции на временной шкале показывают, когда эта точка останова срабатывает. Например, можно использовать команду bp Set Breakpoint. При наведении указателя мыши на точку останова отображается адрес и указатель инструкции, связанный с точкой останова.
После очистки точки останова связанная временная шкала точек останова автоматически удаляется.
Вызовы функций
На временной шкале отображаются позиции вызовов функций. Чтобы выполнить этот шаг, укажите поиск в виде module!function. Примером является TimelineTestCode!multiplyTwo. Можно также указать подстановочные знаки, например TimelineTestCode!m*.
При наведении указателя мыши на вызов функции имя функции, входные параметры, их значения и возвращаемое значение отображаются. В этом примере показаны буфер и размер, поскольку они являются параметрами для DisplayGreeting!GetCppConGreeting.
Обращение к памяти
Используйте временную шкалу доступа к памяти , чтобы узнать, когда определенный диапазон памяти был считыван или записан в, или где произошло выполнение кода. Адреса запуска и остановки используются для определения диапазона между двумя адресами памяти.
При наведении указателя мыши на элемент доступа к памяти появляется значение и указатель инструкции.
Работа с временными шкалами
Вертикальная серая линия перемещается вместе с курсором, когда вы наводите его на временную шкалу. Вертикальная синяя линия указывает текущую позицию трассировки.
Выберите значки с изображением лупы, чтобы увеличить или уменьшить масштаб на временной шкале.
В верхней области управления временной шкалой используйте прямоугольник для сдвига представления временной шкалы. Перетащите внешние разделители прямоугольника, чтобы изменить размер текущего представления временной шкалы.
Движения мыши
Чтобы увеличить и уменьшить масштаб, нажмите клавиши CTRL и используйте колесико прокрутки.
Чтобы сдвинуть с стороны на сторону, выберите shift и используйте колесико прокрутки.
Методы отладки временной шкалы
Чтобы продемонстрировать методы отладки временной шкалы, здесь повторно используется руководство по отладке с путешествием во времени. В этой демонстрации предполагается, что вы завершили первые два шага для создания примера кода и создали запись TTD с помощью первых двух описанных здесь шагов.
В этом сценарии первым шагом является поиск исключения в трассировке перемещения по времени. Дважды щелкните единственное исключение, которое отображается на временной шкале.
В окне командной строки вы увидите, что при выборе исключения была выдана следующая команда.
(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) указывают на разные адреса. Это несоответствие может указывать на повреждение стека. Возможно, функция вернулась и вследствие этого поврежден стек. Чтобы проверить эту проблему, вернитесь к моменту до повреждения состояния процессора и проверьте, можно ли определить, когда произошло повреждение стека.
По мере выполнения этого процесса изучите значения локальных переменных и стека:
- Выберите "Просмотреть>локальные" для отображения локальных значений.
- Выберите «Вид»>«Стек», чтобы отобразить стек выполнения кода.
В момент сбоя в процессе трассировки обычно происходит выполнение нескольких шагов после истинной причины в коде обработки ошибок. При путешествии по времени можно вернуться к одной инструкции за раз, чтобы найти истинную первопричину.
На ленте "Главная " используйте команду "Шаг назад" , чтобы выполнить шаг назад три инструкции. По мере выполнения этого процесса продолжайте изучать окна Stack, Locals и Registers .
В окне Команды отображаются позиция путешествия во времени и регистры, когда вы возвращаетесь на три инструкции назад.
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 байта, чтобы при добавлении их к начальному адресу
Теперь вы можете пройти по ленте времени в обратном направлении, чтобы изучить, в какой момент в этом процессе трассировки этой памяти было произведено записывание, чтобы увидеть, что можно обнаружить. При выборе этой позиции на временной шкале можно увидеть, что локальные значения отличаются значениями для копируемых строк. Конечное значение, как представляется, является неполным, как если бы длина строки не была правильной.
Снимок экрана: шкала доступа к памяти и окно "Локальные переменные", в котором отображаются значения локальных переменных с различными исходными и конечными значениями.
Временная шкала точки останова
Использование точек останова — это распространенный подход для приостановки выполнения кода на каком-то событии, интересующем вас. С помощью TTD можно задать точку останова и вернуться назад до тех пор, пока эта точка останова не будет достигнута после записи трассировки. Возможность проверить состояние процесса после возникновения проблемы, чтобы определить оптимальное расположение точки останова, позволяет больше рабочих процессов отладки, уникальных для TTD.
Чтобы изучить альтернативный метод отладки временной шкалы, выберите исключение на временной шкале и еще раз выполните три шага назад с помощью команды "Шаг назад " на ленте "Главная ".
В этом маленьком примере легко просмотреть код. Если у вас есть сотни строк кода и десятки вложенных объектов, используйте описанные здесь методы, чтобы уменьшить время, необходимое для поиска проблемы.
Как упоминалось ранее, базовый указатель (esp) указывает на текст сообщения вместо указания инструкции.
ba Используйте команду, чтобы задать точку останова для доступа к памяти. Вы устанавливаете точку w - останова на запись, чтобы отслеживать, когда данные записываются в эту область памяти.
0:000> ba w4 003cf7c8
Хотя вы используете простую точку останова доступа к памяти, можно создать точки останова для более сложных условных операторов. Дополнительные сведения см. в разделе bp, bu, bm (Set Breakpoint).
В меню "Главная " выберите "Вернуться назад" до тех пор, пока точка останова не будет достигнута.
На этом этапе вы можете проверить стек программ, чтобы узнать, какой код активен.
Поскольку маловероятно, что предоставляемая корпорацией Майкрософт функция может иметь ошибку в коде, подобную этой, ищите дальше в стеке. Стек показывает, что Greeting!main вызывает Greeting!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 WinDbg.