Отладочная пауза в функциях Win32 Api

Я хотел бы сделать перерыв в функции SetTimer, чтобы посмотреть, какие компоненты регистрируют какие таймеры с какими значениями. Это возможно?


person ronag    schedule 20.06.2010    source источник


Ответы (2)


Да, ты можешь это сделать. Сначала убедитесь, что для отладчика настроены открытые символы.

SetTimer живет в user32, но это именно то, что экспортируется как. Проще всего это сделать с помощью отладчика командной строки NTSD. Нам нужно его настоящее имя, поэтому ищем символы в user32, которые соответствуют:

0:000> x user32!*timer*
759992b9 USER32!NtUserValidateTimerCallback = <no type information>
759977d5 USER32!NtUserSetTimer = <no type information>
759e4f13 USER32!NtUserSetSystemTimer = <no type information>
759993bf USER32!NtUserKillTimer = <no type information>

Ах-ха! Его символ отладки — NtUserSetTimer:

0:000> bp user32!NtUserSetTimer

В Visual Studio вы можете выяснить, где живет SetTimer, написав простую временную программу, а затем установив точку останова, щелкнув правой кнопкой мыши и выбрав «Перейти к дизассемблированию»:

int _tmain(int argc, _TCHAR* argv[]) {
  SetTimer(NULL, 0, 0, NULL);
004113BE  mov         esi,esp 
004113C0  push        0    
004113C2  push        0    
004113C4  push        0    
004113C6  push        0    
004113C8  call        dword ptr [__imp__SetTimer@16 (418338h)] 

Если мы вступим в этот вызов, то приземлимся здесь:

_NtUserSetTimer@16:
759977D5  mov         eax,123Dh 
759977DA  mov         edx,7FFE0300h 
759977DF  call        dword ptr [edx] 
759977E1  ret         10h  

Таким образом, чтобы установить точку останова в Visual Studio, вы должны использовать оператор контекста в точке останова. Выберите в меню: Debug -> New Breakpoint -> Break at Function, затем введите:

{,,user32.dll}_NtUserSetTimer@16
person i_am_jorf    schedule 20.06.2010
comment
Я не знал, что точки останова можно устанавливать с помощью команд. Я никогда не использовал эту функцию. Куда вводить предоставленную вами строку? - person ronag; 20.06.2010
comment
Первый предназначен для отладчика командной строки: microsoft.com/whdc/devtools/ отладка/default.mspx - person i_am_jorf; 20.06.2010
comment
,,user32.dll}_NtUserSetTimer@16 у меня не ломается. Я пробовал следовать вашим инструкциям: 006CD0BD FF 15 4C BA 80 00 call dword ptr [__imp__SetTimer@16 (80BA4Ch)] (8088F8h)], eax перейти в [__imp__SetTimer@16 (80BA4Ch)] //7E418C2D 90 nop 7E418C2E B8 1E 12 00 00 mov eax,121Eh 7E418C33 BA 00 03 FE 7F mov edx,7FFE0300h 7E418C38 FF 12 call dword ptr [edx] 7E418C3A C2 10 00 ret 10h //7E418C3D 90 nop Не получать метку для функции. - person ronag; 21.06.2010
comment
Кажется, у меня нет символов отладки в моей разборке - person ronag; 21.06.2010
comment
Ага, перейдите по первой ссылке про публичные символы. Добавьте http://msdl.microsoft.com/download/symbols в список в Инструменты -> Параметры -> Отладка -> Символы. Возможно, вы захотите установить флажок «Единственная загрузка вручную», чтобы VS не работал очень медленно все время. Затем просто щелкните правой кнопкой мыши user32.dll (или что-то еще) в окне модулей и выберите «Загрузить символы». - person i_am_jorf; 21.06.2010
comment
мой следующий вопрос заключается в том, как я могу увидеть стек памяти потоков? Чтобы тоже посмотреть, с какими параметрами была вызвана функция. - person ronag; 21.06.2010
comment
Это гораздо более сложный ответ. Лучше задать новый вопрос. - person i_am_jorf; 21.06.2010

Вот пошаговое руководство с скриншоты для VS2005. Обратите внимание, что для VS2008+ вам не нужно вводить оформленные имена функций (возможно, поэтому предыдущее описание не сработало напрямую? Какая у вас платформа/IDE?).

[Редактировать:] Вам определенно нужны общедоступные символы MS, чтобы иметь возможность находить Win32 API в двоичных файлах. Самый короткий путь — перейти в Инструменты/Параметры/Отладка/Символы, затем вставить 'http://msdl.microsoft.com/download/symbols» в «расположение pdb». Настоятельно рекомендуется — но не обязательно — устанавливать локальный кеш для загруженных pdb (первая загрузка pdb может занять несколько минут), и для ваших нужд вам, вероятно, следует снять флажок «Искать в вышеуказанных местах только тогда, когда символы загружаются вручную». Будет некоторая задержка запуска, так как все символы загружены, но вам не придется преследовать user32.dll (или любую другую dll, содержащую функцию, которую вы хотите прервать) и загружать ее pdb вручную.

person Ofek Shilon    schedule 20.06.2010
comment
Затем вы можете попробовать либо {,,user32.dll}NtUserSetTimer, либо {,,user32.dll}SetTimer. - person Ofek Shilon; 21.06.2010
comment
Использовать сервер символов Microsoft для получения файлов символов отладки, необходимых для выполнения этой задачи? - person ronag; 21.06.2010