Breakpoints
What is a breakpoint
Run, code and other breakpoints
The squiffy window
Running to the next RET
Running to a new thread
Running to any message
Running to message ..
Message break when single-stepping
Running to code address
Running to a procedure
Running to an exception or API error
Previous breakpoints appear in the menu
Cancelling a run breakpoint
Inserting your own code breakpoint
Cancelling code breakpoints
Inserting your own code breakpoint using INT 3
Inserting your own code breakpoint using DebugBreak

What is a breakpoint
A breakpoint is a point in the code at which execution will stop, and the debuggee will come into the debug loop. At this point GoBug will come into the foreground. If you want to examine execution of code instructions after that point you can do so by single-stepping through the code. Setting a breakpoint enables your program to run quickly to the point which you want to examine.

Run, code and other breakpoints
A run breakpoint causes all the threads of the debuggee to run to the breakpoint. When you use a run breakpoint (other than run to next RET) you lose the opportunity to single-step through code, until the breakpoint is reached. A code breakpoint does not affect the action of the debuggee, since it is achieved simply by inserting a static INT 3 in the code. You can single-step to that point or let one of the threads of the debuggee reach it of its own accord. There are also other types of breakpoints, which cause the debuggee to break automatically, such as if there is an exception or API error or a message occurs when single-stepping.

The squiffy window
When you set a run breakpoint the GoBug displays a squiffy window which gives details of the breakpoint. You can cancel the breakpoint by clicking the "cancel" button.

Running to the next RET
If you are single-stepping through code and find yourself in a long procedure by mistake, click on the menu item "action, run to .., run to next RET", or press the keys Crtl-R. This will cause the thread you are looking at to run to the next RET instruction. Of course, this only works if the debuggee is at the input gate. Don't use this if you are single-stepping from the starting address. In that case the code may never go to a RET because it will probably in due course be entering the message loop or it may eventually call ExitProcess without entering the message loop if it is a console process. Running to RET does not release the trap flag. A full log is kept of events and messages on the way to the RET but not of instructions. This makes it quicker to get there.

Running to a new thread
This breakpoint is reached at the start of the next new thread. It is useful if you are not interested in the current thread but want to examine execution of code by the new thread. Click on the menu item "action, run to .., run to new thread", or press the keys Crtl-N. The trap flag is released and no log of instructions or messages is kept until the new thread is created.

Running to any message
This is a quick way to watch execution of code in a window procedure. This breakpoint halts execution at the beginning of the first window procedure to receive a message (whether directly from the system or via the message queue). Click on the menu item "action, run to .., run to any message", or press the keys Crtl-A. The trap flag is released and no log of instructions or messages is kept until the message occurs. Of course this breakpoint only works if the debuggee has a message queue and therefore receives messages! Note that if your debuggee is running on a battery powered machine, then it regularly receives the WM_POWERBROADCAST message, which will be caught by the breakpoint. If you don't want to debug this message you can be more specific in your message breakpoint (see below).

Running to message ..
This breakpoint allows you to specify which message or messages will halt execution and, indeed, (if symbols are loaded) in which window procedure. Click on the menu item "action, run to .., run to message ..", or press the keys Crtl-M.

The messages are in categories in the tree view control. You can choose to break on categories of message or, by opening the relevant part of the tree view, you can break on a single message. Alternatively you can enter the name of a particular message in the edit control at the bottom of the dialog box. You may also insert here the value of a message (use the format eg. 404h). This is useful if you want to break on receipt of a user-defined message.
Some Windows messages have the same value. This is possible because they will always go to different window procedures. For example, TB_CHECKBUTTON, SB_GETTEXTA, TBM_GETRANGEMAX, PBM_SETPOS, HKM_GETHOTKEY, WM_PSD_MINMARGINRECT, and DM_REPOSITION all have the value 402h. Note that all these messages are used in specific window procedures, so there is no danger of them being confused by the system. Since they have the same value GoBug will only break on that value if the message is destined for, or in the case of a notify message has come from, a window of the correct type to suit the message. The Squiffy window shows the type of window suitable for the message.
Some of the messages listed in the message tree view are sent as a code with one of the notification message carriers, WM_COMMAND, WM_NOTIFY, WM_DEVICECHANGE or WM_POWERBROADCAST. The code which is sent is itself known as a "notification message". When these are chosen for the breakpoint, GoBug looks for the message carrier and then checks to see if the code being sent corresponds with the chosen notification message. GoBug also checks the type of window expected to send the message. All notification messages are listed in the message tree view. The tree view shows the message carrier in parenthensis. In Microsoft tradition all negative notify messages are shown in decimal values instead of in hex as normal.
As new messages are added in new versions of Windows, these will not be in your version of GoBug. If you find they are not in the latest version of GoBug, they may be in a GoBug update. If there are still messages missing, please let Jeremy Gordon know (JG@JGnet.co.uk). For the time being when entering a breakpoint, you can enter the actual value of the message in the edit control at the bottom of the dialog box.
If symbols are loaded, you can limit the breakpoint to the chosen message or messages reaching a particular window procedure by clicking on the drop-down combo box at the top of the dialog. Initially this combo box holds the name of all procedures ending in "proc" (not case sensitive). It is traditional to call a window procedure something proc. But you can obtain the names of all other code procedures by clicking on the "browse" button on the top right hand side of the dialog. Return to procedures ending in "proc" by clicking there again. Note that, unlike in other dialog boxes showing symbols, the symbols which are shown in the combo box comes from all loaded executables in one go, (including dlls) in alphabetical order.
When you use this breakpoint, the trap flag is released and no log of instructions or messages is kept until the breakpoint is reached.
If the expected message does not arrive at the expected place, GoBug does not break. There could be several reasons for the message not to arrive. It may not be dispatched by the message loop, or it may swallowed by the system. There are differences in behaviour between the various versions of Windows. In particular some messages are not used at all in some versions of Windows - see the SDK.

Message break when single-stepping
Messages sent to the window procedures in your application will also cause a break if you are single-stepping (F5 action) and you have the menu item "action, single-step message break" checked. See single-step message break for more information about this.

Running to code address
This breakpoint allows you to specify a code address at which execution will stop and from which you can single-step. In order to find out where you want your breakpoint you will probably need to view the relevant area of code in the codepane or in a code inspector. Alternatively the code address of a procedure may appear in a map file produced by the linker.
When you use this breakpoint, the trap flag is released and no log of instructions or messages is kept until the breakpoint is reached.
If symbols are loaded and recognised by GoBug, you will find running to a procedure to be much easier to use.

Running to a procedure
This breakpoint allows you to specify, by reference to code symbols, a code address at which execution will stop and from whcih you can single-step. You can only use this method of choosing a breakpoint if symbols have been loaded and recognised by GoBug.

Running to an exception or API error
GoBug always breaks if an exception occurs. GoBug will also break if an API error occurs if the menu item "action, break on API error" is checked. If you want to run to an exception or API error, you can choose whether to use F7 (run/trap/hook/full log), F8 (run/hook/part log) or F9 (run in the background). Which one you choose depends on how much information you need when the exception or error occurs, see how debug action affects what is logged, and also the stacktrace.

Previous breakpoints appear in the menu
To help you set a breakpoint quickly, your last ten breakpoints for the same debuggee appear in the "action" menu itself. Click on one of these to run to that breakpoint. If you have re-assembled or re-compiled your program since you last used one of these breakpoints, you may find that specific code addresses have moved, so treat these with some caution. In the case of code addresses chosen by a symbol, GoBug searches for the same symbol again, so that it will not matter if the actual code address for a particular symbol has moved. In the case of message breakpoints, the menu also shows the window type and the chosen window procedure if that was specified.

Cancelling a run breakpoint
Click "cancel" on the squiffy window which appears above GoBug's main panes when running to a breakpoint.

Inserting your own code breakpoint
Double click the codepane at the address where you want to insert a code breakpoint.
Alternatively if the codepane has the key focus press enter to change the focus rectangle to a highlight then press enter again to make the code breakpoint. If the line is already highlighted, then you need to press enter only once.
In effect this inserts an INT 3 into the code which will stop execution at that point and take the debuggee into the debug loop. You can set as many code breakpoints as you like. A maroon line appears in the codepane at each one. If you want to set a code breakpoint which is outside the section currently being shown in the codepane, click on the menu item "inspect, codepane to view code at .., code address" to reach a dialog which will enable you to view other sections and find the right place for your breakpoint. Setting a code breakpoint has a static effect, that is you yourself can choose the debuggee action which will cause execution to reach the breakpoint. Once there, the debuggee is in the debug loop and you can choose any action - this will jump over the INT 3 in the code, execute the original opcodes which were there before the INT 3 was inserted, and continue executing normally.

Cancelling code breakpoints
You can cancel a single code breakpoint by double clicking on it.
Alternatively if the codepane has the focus move the focus rectangle to the code breakpoint and press enter. The breakpoint line will darken (indicating is has the highlight), and then press enter again. If the breakpoint is already dark you only need to press enter once.
You can cancel all code breakpoints at once by clicking on the menu item "action, delete all code breakpoints". Setting a Run to .. breakpoint will cancel all code brealpoints too (except for Run to .. RET).

Inserting your own code breakpoint using INT 3
If you insert the mnemonic INT 3 in your source code execution will stop at that point and the debuggee will enter the debug loop, allowing you to single-step from that point. This is a useful method of using breakpoints if you don't have symbols loaded which GoBug recognises.

Inserting your own code breakpoint using DebugBreak
If your assembler or compiler does not permit you to insert INT 3 in your source code, then you can call the API DebugBreak. This does exactly the same thing, the only difference being that the INT 3 is in system code, since it is called within one of the system Dlls. You can then easily single-step back into your own source code.