Other techniques to try
Other techniques to try (instead
of debugging)
Examine your code
Retrace the steps prior to the bug
Slow down the system at run-time for draw problems
Remove parts of your code
Add a visible tester to your code at the point of error
Dedicate a key during your application's development
which shows the tester window
Finding fixup or linking problems where the source
code line is not known
-
Examine your code
Often there is no substitute for a hard look
at your source code to see where the error has occurred. This will
be made much easier if you add and test your source code incrementally.
In other words add small chunks of code bit by bit, and then test it, rather
than adding large sections, which might contain more than one fault which
may interact with each other.
-
Retrace the steps prior
to the bug

Try to note the sequence of events leading up to the bug each time the fault occurs. Then carry out that sequence again to check that the
fault then occurs. Try to isolate the fault by removing some of the steps
or by taking other steps. Get the sequence as short as you can. This process
will help to find the most likely culprit for the fault, and reduce the
procedures that you need to check.
-
Slow down the system at run-time for draw problems

If you have a Windows drawing problem where you suspect Windows is drawing something to the screen and then drawing over it with something else, try slowing down your programs by inserting, at an appropriate point:-
PUSH 1000
CALL Sleep
This calls the API Sleep, with a delay of 1,000 milliseconds.
This API will act only on the thread by which it is called, so if you
suspect that another thread is writing over material from the first thread
this technique should make this apparent. [Note it is not a good
idea in any Windows application to have more than one thread responsible
for drawing to the screen or managing windows since this is bound to confuse
the system].
If the over-write is occurring within your own code in response to
the WM_PAINT message, then insert the Sleep API call at appropriate places
in your painting process to discover exactly where the over-write is occurring.
Windows will sometimes draw over what you have tried to draw to the
screen. This might occur, for example, if the system is of the belief
that another window should appear on top of the draw (ie. another window
is higher in the Z-order) or if the system believes the area you have drawn
onto is "invalid" (requires painting because it has moved or been uncovered).
Bear in mind that the system will not do any further drawing in a window
until the thread which has created that window returned from its WndProc
or until DefWindProc is called. So you can insert the Sleep API prior
to doing this.
-
Remove parts of your code

This is another useful technique to identify over-write problems, whether to the screen or to memory. Remove the suspected code using a colon
at the front of the line of code, so that the assembler ignores that line.
See if it corrects the problem. Of course, you have to be careful
to ensure that all necessary register and memory values are provided to
later lines of code, and that the equillibrium of the stack is maintained.
-
Add a visible tester to your
code at the point of error

Here you arrange for a "Tester window" to appear on the screen when a particular part of the code is reached. In the example code which you can view (click on the link below), the tester window displays in hex the value of the EAX register. It saves all the registers and flags
and is therefore transparent to the program. If the tester is called
again it adds another line to the tester window with the value of EAX at
that time. Each line is numbered and can be viewed by scrolling.
There are two things to be cautious about here. Firstly be careful
using this method if you have painting and drawing problems since the tester
itself may cause your application to carry out further painting and drawing.
Secondly, when inserting the tester in a secondary thread, don't call the
tester directly from that thread. Instead, send a message to the main window
and call the tester from there to avoid inter-thread problems.
 Tester window code.
-
Dedicate a key during your
application's development which shows the tester window
Here you respond to a specific key and WM_KEYDOWN by calling the tester. You can load into EAX whatever memory value you want to study.
When your program is finished and ready for publication ensure that this
code is removed. This is a quick way to view memory values without
having to start the debugger. Again you can call the tester as many
times as you like, the results will simply scroll in the window.
This technique can also be used to check the results of your coding in
more detail. For example, when the key is pressed arrange to call
the function under test, passing it various values. Read the result
to check it is working alright.
-
Finding fixup or linking
problems where the source code line is not known

Sometimes your linker will report a fixup or linking problem without identifying the exact position in your source code. These problems can be most difficult to find, and this is one of the reasons why you should code incrementally, testing each new piece of code as it is written. If you do need to find a problem of this sort and you cannot identify from the output of the linker where the problem lies, try inserting a NOP mnemonic at various points in your source code (but have only one NOP there at any one time). The instruction address below the NOP will be increased by 1 byte. If the error address now changes, you know that the error is below the NOP. Alternatively you can comment-out a line containing a relocation (memory address of a symbol) which will have the effect of reducing the error address by a few bytes if it lies below the line. You can make a rough guess of the position of the error in your source code by comparing the top address or total number of relocations and compare that with the figure given in the error message. Remember if you have several OBJ files that the linker will probably link them in the order they are read, so check the sequence of OBJ files presented to the linker to get some idea which file the problem lies in if this is not reported by the linker.