2

我正在编写一个 Windows 调试器,所以我有通常的 ContinueDebugEvent/WaitForDebugEvent 循环:

while (true)
{
 ContinueDebugEvent(hTargetProcessId, hTargetThreadId, lastDebugResult);
 WaitForDebugEvent(&evt, INFINITE);
 ...
 hTargetThreadId = evt.dwThreadId;
}

这很好用,但我正在添加一个需要能够在调试过程中执行特定线程的功能。为此,我暂停了所有我不感兴趣的线程,就像这样(为简洁起见,我省略了一些代码 - 希望这足够清楚!):

while (true)
{
 if (onlyACertainThread)
 {
  for (int n=0; n<threadcount; n++)
   if(threads[n] != certainThread)
    SuspendThread(threads[n]);
 }

 ContinueDebugEvent(hTargetProcessId, hTargetThreadId, lastDebugResult);
 WaitForDebugEvent(&evt, INFINITE);

 if (onlyACertainThread)
 {
  for (int n=0; n<threadcount; n++)
   if(threads[n] != certainThread)
    ResumeThread(threads[n]);
 }
 ...
 (code to add to 'threads', update threadcount, decide if we want to restrict to a certain thread, etc)
 ...
 hTargetThreadId = evt.dwThreadId;
}

但是,我经常看到来自错误线程的调试事件。例如:

  • 线程 A 正在运行
  • 决定我们要观察线程B;挂起线程 A,调用 continue/waitfordebugevent(.. A.pid..)
  • 从线程 A 获取调试通知(断点、异常)。

我想要的是最后一步是“从 B 获取通知”。我试过调用 WaitForDebugEvent(..B.pid..) 不起作用。

这是预期的行为吗?

我怀疑线程挂起/恢复计数器仅在线程被调度时被内核观察到;即,在时间片结束时。这将导致线程 A 继续运行,直到其当前时间片结束。任何人都可以确认/否认这个想法吗?如果是这样..我将如何解决它?目前我最好的想法是在暂停线程后“注入”对 Sleep(0) 的人工调用,但我真的不想这样做,除非我必须这样做!

如果有什么不同的话,我运行的机器是一个单线程的 XP 机器。

4

0 回答 0