Отладка приложений


         

если GetLastError возвращает код ошибки


Например, если GetLastError возвращает код ошибки 122, это означает, что параметр размера буфера был слишком мал. Файл WINERROR.H содержит все коды ошибок, которые возвращает операционная система. Проблема с функциями подключения состоит в том, что в процессе обработки они могут переустанавливать последнюю ошибку. Такое поведение может нанести ущерб, если приложение полагается на значение последней ошибки.

Если вы вызываете функцию createEvent и хотите увидеть, был ли дескриптор возвращен или только открыт, то имейте в виду, что в том случае, когда она только открыла дескриптор, эта функция устанавливает для последней ошибки код ERROR_ALREADY_EXISTS (ошибка уже существует). Поскольку  кардинальное правило перехвата функций заключается в том, что нельзя изменять ожидаемое поведение функции, нужно было вызывать GetLastError сразу же после вызова реальной функции, так чтобы функция подключения могла должным образом устанавливать код последний ошибки, который возвратила реальная функция. Общее правило для функции подключения — нужно вызвать GetLastError сразу же после вызова реальной функции, а затем setLastError — как последнее действие перед выходом из функции подключения.

К сожалению, первый же тест обнаружил ошибку: я не сохранил содержимое регистров ESI и EDI во время вызова подключения, потому что документация по использованию встроенного ассемблера явно утверждала, что их не нужно сохранять. После того как проблема регистров ESI/EDI была решена, DeadlockDetection, казалось, заработала прекрасно. Однако, когда я начал сравнивать содержимое регистров до, в течение и после некоторых событий, я заметил, что не возвращал значений реальных функций, остававшихся в регистрах ЕВХ, ЕСХ, и EDX, и еще хуже, — в регистрах флажков. Хотя я не видел никакой проблемы, и документация говорила, что эти регистры не нужно сохранять, я все же был обеспокоен тем, что функции подключения, возможно, изменяли состояние приложения. Я объявил структуру REGSTATE для хранения значений регистра после вызова реальной функции, так чтобы появилась возможность восстановить их при возврате из функции подключения.

Содержание  Назад  Вперед