В настоящее время я выполняю последнюю задачу для небольшой среды отладки, а именно HW Breakpoints.До сих пор я ссылался на эту статью: http://www.codeproject.com/KB/debug/hardwarebreakpoint.aspx и книгу о написании отладчика.
До сих пор я получил две функции для установки точки останова HW:
void debuglib::breakpoints::hw_bp() {
HANDLE helper = 0;
CONTEXT co;
CURRENTCONTEXT(co);
helper = ::CreateThread(0,0,threadfunc,reinterpret_cast<void*>(co.Eip),0,0);
DWORD status = ::WaitForSingleObject(helper,INFINITE);
if (status != WAIT_OBJECT_0) {
::MessageBoxA(0, "Helper thread didn't exit cleanly", "HWBreakpoint", MB_OK);
}
::CloseHandle(helper);
}
static DWORD WINAPI debuglib::breakpoints::threadfunc(void* param) {
DWORD suspendcnt = ::SuspendThread(debuglib::process::thread());
if(suspendcnt) {
return 0;
}
CONTEXT co;
::ZeroMemory(&co,sizeof(co));
co.ContextFlags = CONTEXT_DEBUG_REGISTERS;
BOOL ok = ::GetThreadContext(debuglib::process::thread(),&co);
if(!ok) {
return 0;
}
DWORD freeDr = 0;
DWORD condition = debuglib::breakpoints::TRIGGER::CODE;
DWORD length = debuglib::breakpoints::SIZE::SIZE_1;
co.Dr0 = reinterpret_cast<DWORD>(param);
co.Dr7 = co.Dr7 | 1 << (freeDr*2);
co.Dr7 = co.Dr7 | condition << ((freeDr*4)+16);
co.Dr7 = co.Dr7 | length << ((freeDr*4)+18);
co.ContextFlags = CONTEXT_DEBUG_REGISTERS;
ok = ::SetThreadContext(debuglib::process::thread(), &co);
co.ContextFlags = CONTEXT_DEBUG_REGISTERS;
::GetThreadContext(debuglib::process::thread(),&co);
suspendcnt = ::ResumeThread(debuglib::process::thread());
if(suspendcnt == 0xFFFFFFFF) {
return 0;
}
return 1;
}
Итак, сначала я создаю вспомогательный поток, так как я отлаживаю текущий поток.В функции обратного вызова вспомогательного потока я приостанавливаю основной поток.После этого я читаю текущие значения DR основного потока (на данный момент это не актуально, так как я всегда использую DR0, после этого я проверю, какие регистры свободны и используют до 4 BP).Впоследствии я использовал адрес возврата вызывающей функции (EIP) в качестве адреса для разрыва в DR0 и установил соответствующие флаги в DR7.
В конце я возобновляю основной поток и закрываю дескриптор помощника.поток, как он закончен.
С этим кодом у меня возникла следующая проблема:
Если я выполняю программу в режиме отладки, программы останавливаются по правильному адресу, но я больше ничего не могу сделать,так как флаг INT1 установлен, я полагаю, и отладчик VS не может двигаться дальше ни на шаг?
Если я запускаю программу без отладки, она просто вылетает.Я пытался использовать __try, __except, как в упомянутом проекте (http://www.codeproject.com/KB/debug/hardwarebreakpoint.aspx), но это тоже не работает.
Я ценю и помогаю, или сообщаю, что я делаю неправильно и как решить эту проблему.