【问题标题】:Hardware breakpoints EXCEPTION_SINGLE_STEP all the time硬件断点 EXCEPTION_SINGLE_STEP 一直
【发布时间】:2015-05-31 00:04:54
【问题描述】:

我有一个用作调试器的程序。我为线程设置了一个 hw bp,将 dr0 设置为我希望 bp 所在的地址,将 dr7 设置为 1,因为我希望 bp 在每次执行该地址时生成一个事件。

它有效,但现在的问题是我不会一直停止接收 EXCEPTION_SINGLE_STEP。我像往常一样用 WaitForDebugEvent 创建了一个循环:

DebugActiveProcess(pid);
while (flag == 0)
    {
        WaitForDebugEvent(&DBEvent, INFINITE);
        if (first_time){
            setHWBPInCurrentThreads(pid, breakpoint_address);
            first_time = 0;
        }
        switch (DBEvent.dwDebugEventCode)
        {
            // Here we check if a new thread is created and we set a BP for all of them
            case CREATE_THREAD_DEBUG_EVENT: 
            {
                HANDLE thread_handle = DBEvent.u.CreateProcessInfo.hProcess;
                HANDLE hX3 = SetHardwareBreakpoint(thread_handle, HWBRK_TYPE_CODE, HWBRK_SIZE_1, breakpoint_address);

            }break;

            case EXCEPTION_DEBUG_EVENT:
            {
                switch (DBEvent.u.Exception.ExceptionRecord.ExceptionCode)
                {
                case EXCEPTION_SINGLE_STEP:
                {       
                    printf("%d\n", DBEvent.dwThreadId);
                    ///MessageBoxA(0, "yesssssssss", "", 0);
                }break;

                case EXCEPTION_BREAKPOINT:
                {
                    //MessageBoxA(0, "Found break point", "", 0);

                }break;
                }
            }break;

        }

        ContinueDebugEvent(DBEvent.dwProcessId, DBEvent.dwThreadId, DBG_CONTINUE);
                }

这里有什么问题?我应该怎么做才能让异常消失并且只有在下次执行地址时才能获得控制权?

【问题讨论】:

  • 您过早停止编写代码。断点命中后,调试器 UI 接管,程序员决定下一步做什么。现在什么都没有发生,你立即调用 ContinueDebugEvent() ,这当然会再次触发断点。

标签: c++ c debugging hardware breakpoints


【解决方案1】:

即使在断点被击中后,您的实现也只是继续调试事件,这将在无限循环中再次触发断点。

根据您使用的环境,需要以不同方式处理正确的实现。如果您在比 Windows XP 更新的环境中进行调试,则处理断点的方式是:

  1. 设置恢复标志 (EFLAG)。
  2. 继续调试事件(ContinueDebugEvent)。

如果您确实在 Windows XP 环境中工作,您的实现需要更改为:

  1. 禁用断点 (Dr7)。
  2. 设置陷阱标志 (EFLAG)。
  3. 继续调试事件(ContinueDebugEvent)。
  4. 等待陷阱标志引起的 EXCEPTION_SINGLE_STEP(您现在处于下一条指令)。
  5. 启用断点 (Dr7)。
  6. 继续调试事件(ContinueDebugEvent)。

很抱歉打扰了这个旧线程,但是,这些是正确的实现。

【讨论】:

    【解决方案2】:

    我终于知道发生了什么: 硬件 bp 的工作方式与软件 bp 不同。使用软件断点,您只需调用 ContinueDebugEvent 并等待下一个事件发生(达到 bp)。

    使用 HW bp,您需要首先重置 Dr0-Dr3、Dr6 和 Dr7 寄存器,然后调用 ContinueDebugEvent,然后再次设置寄存器,就像事件发生时一样。这很令人困惑,因为ContinueDebugEvent 的行为方式与软件断点中的不同。

    我希望这可以帮助其他有同样问题的人。

    干杯

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-28
      • 1970-01-01
      • 1970-01-01
      • 2019-09-01
      • 2016-02-09
      • 2012-04-07
      • 1970-01-01
      • 2021-04-10
      相关资源
      最近更新 更多