In the context of a debugger, a breakpoint is a specific condition, usually set manually, that causes the debugger to pause the execution of the program, allowing a person to inspect its internal states. That condition is most often the execution of the instruction at a certain memory location (i.e. a certain value of the program counter), and such a breakpoint is called an instruction breakpoint. Other common conditions are when a certain memory location is read, written to, or jumped to. In uncommon cases, more complicated conditions (usually a combination of several conditions) may be needed for a specific debugging purpose.
Since instruction breakpoints are the most common kind of breakpoints, the word "breakpoint" may mean "instruction breakpoint" by default. For example, "a breakpoint at $0040" is understood as a breakpoint that triggers when $0040 is executed. Breakpoints are often set at the entry points of subroutines, in order to analyze their inner workings.
For a Game Boy system, there are two ways to specify the location of a breakpoint. One way is to simply use the Game Boy memory space of $0000~$FFFF; however, if a two-byte memory address is in the range $4000~$7FFF (switchable ROM) or $A000~BFFF (SRAM), it may refer to multiple actual memory locations, due to those memory ranges being banked (i.e. switchable). Therefore, to remove ambiguity, a three-byte pointer in the form of (Bank):(Pointer) may be used, such as 03:55C7.
When the execution is paused by the debugger, the user is free to use available features of the debugger to inspect the program state at that point, such as the hardware registers, the assembly code around the program counter, and the contents of the RAM.
Setting breakpoints on BGB
In the BGB GameBoy emulator, it is easy to set various kinds of breakpoints. The player needs to first bring up the debugger by right clicking on the Game Boy display, and select Other > Debugger from the menu. Afterwards, there are multiple ways to set breakpoints.
One way is to select Debug > breakpoints or access breakpoints; a dialog will pop up, allowing the player to add, modify, or remove breakpoints at will. The player can also right click on a memory location in the "code" pane or "data" pane on the left side of the debugger, and select Set access breakpoint. This will bring up the same "access breakpoints" window with the memory address already filled in.
Another shortcut is to double click any instruction in the "code" pane. This will add or remove an instruction breakpoint at that instruction.
Special applications in glitching
An easy trick to find potential arbitrary code execution (ACE) exploits is to set a breakpoint on execution of any address in the range of $8000~$FEFF (such a breakpoint can be set in BGB as an access breakpoint). Whenever such a breakpoint is hit, it means that the control flow must have reached the RAM area, indicating a potential ACE exploit.
In the below image, the debugger has automatically paused execution and highlighted WRA1:D163 following the use of the glitch item 8F (0x5D). This means that the game is executing code from $D163, which is a RAM address. By looking in a RAM map, one can see that the values here are the party Pokémon data. Since party Pokémon data are highly controllable by the player, this is indeed an ACE exploit.
From the "code" pane, it can be seen that the data values "03 C3 22 D3", originally the player's party count and party Pokémon species, are interpreted as GBZ80 programming language instructions by the game. By consulting The Big HEX List, the player can design a setup for the ACE exploit from here.