API errors
What is an API error
How the system indicates an API error
Some APIs act differently
Good programming practice
How GoBug watches for, and deals with, API errors
Break on API error

What is an API error
An API error occurs when the API was unable to carry out the requested action for one reason or another. Here the API is acting as designed, in a controlled fashion.

How the system indicates an API error
The system indicates an API error using one or both of the following:-

Some APIs act differently
Some APIs don't use EAX to indicate whether there was an error. Instead they may set the error code to zero to indicate success or to non-zero to indicate failure. Some APIs set the error code to report events in the API rather than to show errors. An example of this happening is CreateFile if (when it is called) the flag dwCreationDistribution is set to 2h (create always). If the file already exists then CreateFile will set the error code to state that, but it returns with a filehandle in EAX as usual. Always check with the SDK how a particular API reports its errors.

Good programming practice
It is good and often essential programming practice to allow for unexpected errors in your application. Such errors can occur easily and not just during development. To take an extreme example, suppose you wish to set up an area of memory to write to using the API VirtualAlloc. To avoid a possible exception occurring, you would check the return from VirtualAlloc before trying to write to memory. If VirtualAlloc gave an error return, you would finish gracefully and inform the user (at least) that the action could not be carried out.
It also makes sense if you ask the system for a handle, to check the return value in EAX before using the handle. For example you would check EAX if you called CreateFile, to see if it has returned a good file handle for a file you wish to write to (value EAX=-1 indicates failure).
And suppose you want to check that the filehandle is still valid after a lot of other processing has taken place before trying to write to the file. You can then call an innocuous API to check the filehandle, such as SetFilePointer with the FILE_CURRENT flag. You would then check the return in EAX from the API or from GetLastError to see if the handle is still valid.

How GoBug watches for, and deals with, API errors
When single-stepping or doing F7 action (run/trap/full log), since the thread which is executing comes into the debug loop after each instruction, GoBug can check the thread's last error code to see if it has changed. If the error code has changed since it was last checked and is larger than zero, and if EAX is zero or -1, GoBug wilI be aware that an API error has just occurred. What happens then is that in the codepane, a red rectangle appears around the offending API call which had the last error for the thread concerned. Details of the API error also appear in the log:-

In this example the error code shown in the log is the name of the constant taken from the system header file, and the description of the error on the line below is a string for the error code obtained from the API FormatMessage.

Break on API error
You can get GoBug to break on any API error by checking the relevant entry in the "action" menu. This only works when doing F7 action (run/trap/full log), since then the thread which is executing comes into the debug loop after each instruction, enabling GoBug to check the last error code. If an API error then occurs, GoBug will come into the foreground and the debuggeee will be suspended in the debug loop, ready for you to see what went wrong. This is a good time to have a look at the stacktrace to see the depth of call at the part of the code that the error occurred. Bear in mind that the part of the stack holding the parameters sent to the API may have been changed by the API itself, and so may not be reliable. However, information about the parameters passed to the API will be available from the instruction logpane, unless they are values at that time held in memory. If the fault is not obvious, to check those parameters, restart the debuggee, set a code breakpoint before the API call, and carry out the same action in the application to get to the same point in execution.