Как правильно удалять аппаратные точки останова

#c #debugging #exception #winapi #breakpoints

#c #отладка #исключение #winapi #точки останова

Вопрос:

Я пытаюсь создать небольшой отладчик с возможностями аппаратной точки останова. Я использую векторную обработку исключений для перехвата исключений, и я столкнулся с проблемой при попытке удалить точки останова:

Когда обработчик сбрасывает регистр Dr6, существует вероятность, что точка останова будет удалена одновременно. Обработчик приостановлен, и его контекст переключается с измененным регистром Dr7, но когда он выходит, контекст снова переключается с регистром Dr7 в его исходном состоянии.

К сожалению, нет способа синхронизировать переключения контекста, поскольку это происходит вне обработчика.

Есть ли способ изменить только определенные регистры, используя CONTEXT::ContextFlags ? Или, возможно, какой-то лучший подход для удаления точек останова в целом?

ОБРАБОТЧИК:

 inline bool handle(_EXCEPTION_POINTERS* t_ExceptionInfo)
{
    if (m_index == 0xFF || t_ExceptionInfo->ExceptionRecord->ExceptionCode != STATUS_SINGLE_STEP || !(t_ExceptionInfo->ContextRecord->Dr6 amp; 1ui64 << m_index))
    {
        return false;
    }

    t_ExceptionInfo->ContextRecord->ContextFlags |= CONTEXT_DEBUG_REGISTERS;
    t_ExceptionInfo->ContextRecord->Dr6 = 0;
    return true;
}
  

УДАЛИТЬ:

 if (SuspendThread(hThread) != -1)
{
    CONTEXT ctx{ 0 };
    ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
    if (GetThreadContext(hThread, amp;ctx))
    {
            ctx.Dr7 amp;= ~(1ui64 << m_index * 2);
            SetThreadContext(hThread, amp;ctx);
    }
    ResumeThread(hThread);
}
  

Комментарии:

1. Почему контекст потока будет меняться между вызовами, если поток приостановлен?

2. Я не знаю об ошибке, с которой вы столкнулись, но вместо этого вы должны использовать WaitForDebugEvent function , также можете ли вы уточнить, что вы имеете в виду, когда говорите resetting the Dr6 register there is a possibility that the breakpoint gets removed at the same time , что точка останова является контекстом для каждого потока, поэтому, если есть объект, который запущен, даже если он способен удалить точку останова из dr0-4, тогда он не будет работатьэто не влияет на поток вашей отладки, можете ли вы попытаться прояснить, поскольку переключение контекста не влияет на регистр dr, поскольку потоки были переключены на другой контекст потока