The various bits in the DR7
(debug control) register determines the applicability of the hardware breakpoint in question. Such breakpoints can be local or global.
Global breakpoint, as its name suggests affects all tasks. Local breakpoint are specific to the currently executing task. For the Intel Architecture, local breakpoint enable flag bits in the DR7 are cleared on every task switch. Global breakpoint are preserved on task switches.
In Windows, you can only set local hardware breakpoints from user mode.
Now, as per intel documentation local hardware breakpoints are cleared on task switch. So how does local hardware breakpoints work ?
Hardware breakpoints work and fire on the correct process because Windows does not use the hardware task state switching machinery available in the processor. Windows has its own mechanism for context switch. During a context switch, the kernel creates a special structure called the TRAP_FRAME
to store information about the debug registers along with other things. The TRAP_FRAME
is a part of the thread's complete context.
When the thread is re-scheduled for execution, Windows restores the saved context and with this hardware breakpoints are restored too.
Hence, the processor can never distinguish between a local hardware breakpoint in Process A and Process B. All it sees is a single task executing on each processor. The responsibility of restoring local hardware breakpoints across various processes lies with Windows.
Replies to the comments
(1) On Windows, hardware breakpoints are thread specific. This means if you set a hwbp on an address from a particular thread, the breakpoint will only be triggered when the thread executes/reads/writes that particular address. HWBP are never process wide. Hence, thread2 will never break for a hwbp set from thread1.
(2) The situation is same for Linux. However, it is most likely different for iOS as it runs on a different architecture i.e ARM and not x86.