This is heavly depend on the CPU and debugger.
For example, one of the possible solution on x86 CPU:
- Insert one-byte INT3 instruction on the required place
- Wait until breakpoint exception hits
- Compare exception address to the list of breakpoint to determine which one
- Do breakpoint actions
- Replace INT3 with original byte and switch the debugged process into trace mode (step-by-step execution of CPU instructions)
- Continue debugged process
- Immediately you catch trace exception - the instruction was executed
- Put INT3 back
Watchpoints can be implemented in the similar way, but instead of INT3 you put the memory page where watched variable is into read only, or into no access mode, and wait for segmentation exception.
Stepping through assembly can also be done by using trace mode. Stepping through source lines can also be done by placing breakpoints onto next instructions, based on debug data.
Also some CPU has hardware breakpoint support, when you just load address into some register.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…