You might have heard of the Popek and Goldberg Virtualization Requirements. In theory, debugger shares a similar set of problems as virtualization, this is especially true for func-eval (Function Evaluation). Here goes a pop quiz about the side effects of the presence of debugger:


#include <Windows.h>

#define LOOPCOUNT 10

ULONG g_ulVariableA;
ULONG g_ulVariableB;

DWORD WINAPI ThreadProcA(LPVOID lpParameter)
    for(int i = LOOPCOUNT; i; i--)
  } // add a breakpoint here (BP1)
  return 0; } DWORD WINAPI ThreadProcB(LPVOID lpParameter) {   while(true)   {     for(int i = LOOPCOUNT; i; i--)       ++g_ulVariableB;   } // add a breakpoint here (BP2)
  return 0; } int ExeEntry(void) {   SetProcessAffinityMask(GetCurrentProcess(), 1);   CloseHandle(CreateThread(NULL, 4096, ThreadProcA, NULL, 0, NULL));   CloseHandle(CreateThread(NULL, 4096, ThreadProcB, NULL, 0, NULL));   return ERROR_SUCCESS; }

Let's say we have two breakpoints BP1 and BP2 as illustrated:

  1. Each time I launched the application from the Visual Studio Debugger on my desktop machine (Xeon Quad core, Windows 7 64bit), BP2 would always get hit before BP1. On my laptop (Dual core, Windows 7 32bit), BP1 will get hit before BP2.
  2. If I made BP2 as a conditional breakpoint with a false condition (e.g. 0 == 1) on my desktop machine, I will have to wait a few seconds before BP1 got hit.
  3. If I made BP1 as a conditional breakpoint with a false condition (e.g. 0 == 1) on my laptop, I never got a chance to hit BP2, and my CPU usage would always stay at around 50%.

Do you share a similar experience as I have? I have already put some hints on the title of this pop quiz, happy debugging :)