Каков наилучший способ подключить отладчик к процессу в VC ++ в нужный момент времени?
-
20-08-2019 - |
Вопрос
При отладке иногда требуется подключить уже запущенный процесс вместо того, чтобы просто запускать приложение в отладчике.
Я обычно использую вызов Sleep() или MessageBox, чтобы было проще подключить отладчик.Я беспокоюсь, что некоторые из них в конечном итоге могут быть переданы в систему управления версиями.
Что лучше всего сделать, чтобы избежать этой ситуации, но при этом отложить достаточно времени, чтобы вы могли подключить свой отладчик к запущенному процессу?
Защита окна ожидания или сообщения с помощью #ifdef _DEBUG
это один из способов, но мне интересно, есть ли способ получше.
Со Сном у вас также возникает проблема, которую вы можете не зафиксировать вовремя.С MessageBox у вас возникает проблема, связанная с тем, что вы, возможно, выполняете удаленную отладку или отлаживаете процесс, у которого нет видимого графического интерфейса пользователя (пример, запущенный как служба в Vista)
Решение
вы можете использовать DebugBreak, проверьте эти ссылки:
http://www.epsilon-delta.net/articles/vc6_debug.html#breaking-with-debugbreak
http://blogs.msdn.com/calvin_hsia/archive/2006/08/25/724572.aspx
Другие советы
Чтобы прикрепить отладчик в определенной точке, у вас есть несколько вариантов:
Самое простое - просто позвонить DebugBreak
, что во многом эквивалентно __asm int 3
, но также работает и на других архитектурах (MSVC для x64 не поддерживает встроенную сборку, если я правильно помню).Откроется окно оперативного отладчика, и вы сможете выбрать один из зарегистрированных отладчиков (т. е.Visual Studio), чтобы подключиться к процессу.
Альтернативно, вы можете позвонить на Sleep
, что дает вам возможность подключить отладчик.Вы должны использовать #ifdef _DEBUG
вокруг этого, чтобы гарантировать, что вы действительно не отправляете продукт с включенным этим кодом.
Один вопрос:почему ты не можешь запустить код из IDE?Это служба, DLL, загруженная в IIS, или что-то подобное?
В этом случае вы можете проверить ImageFileExecutionOptions
ключ реестра, позволяющий подключить отладчик в момент запуска процесса.
Если вы используете для этого cdb, вы можете настроить его как сервер или клиент для экземпляра WinDbg и выполнять отладку таким образом.Раньше я делал это, используя WinDbg в качестве отладчика ядра и используя ImageFileExecutionOptions для запуска. ntsd -d
с указанным процессом.Это приводит к тому, что WinDbg переходит в пользовательский режим.Иногда это полезный метод.
другой вариант, который я иногда использую:
while( !::IsDebuggerPresent() )
::Sleep( 100 ); // to avoid 100% CPU load
он должен просто молча ждать, пока вы не подключите к процессу отладчик.
У Фредди и Реоа есть правильные решения.Но я хотел добавить причину, почему бы не использовать MessageBox.
Отображение MessageBox лишь частично останавливает ваше приложение.Поскольку вы показываете пользовательский интерфейс, насос сообщений все еще работает как минимум в одном потоке вашей программы.Итак, если ваш код выполняет любое из следующих действий.
- Общается через сообщения Windows
- Имеет нетривиальный интерфейс
- Является многопоточным
По сути, вы будете запрашивать отладчик в одном состоянии, но подключаться к вашей программе в совершенно другом состоянии.Это может привести к запутанным ситуациям и ошибкам.
Недавно мы внесли изменения в нашу базу кода, чтобы никогда не отображать MessageBox, чтобы облегчить разрыв именно по этой причине.Это приводит к очень плохому поведению нетривиального приложения.
Прикреплять «в нужной точке» — это боль…один из вариантов — явно указать операторы DebugBreak() в коде, чтобы вызвать проблему, и защитить их с помощью #ifdef _DEBUG
было бы хорошей идеей.Мы используем макрос ASSERT, который может вызывать DebugBreak(), поэтому вы можете просто написать ASSERT(false)
Другой вариант, который следует рассмотреть, — использовать «параметры выполнения файла изображения» для автоматического запуска отладчика.Видеть это блог и MSDN документация.
Посмотри вверх:
DebugBreak , __debugbreak и друзья
или
статический void timeToChase() { __asm { int 3;};}
__asm int 3
Эта жесткая точка останова вызовет диалоговое окно отладки, которое позволит вам подключиться к процессу.Оберните это в #ifdef _DEBUG, и вы будете использовать его только в отладочных сборках.