Debugging

If you are coming from a pure Smalltalk environment you will find the debugging techniques available to Smalltalk MT to be more varied than you are used to. This is for a number of reasons which I will cover here.

Writing Debugging messages

In traditional Smalltalk you would typically use:

Transcript show: 'My debugging message'.

This is not recommended in Smalltalk MT for three main reasons. First, writing to the Transcript is not thread-safe (i.e. it will not always work in a multi-threaded Smalltalk environment). Secondly, there is a faster more standard Windows approach that you may not be aware of. Lastly, writing to the Transcript will not work in runtime since the Transcript does not exist at runtime.

Instead of the Transcript write, use

Processor outputDebugLine: 'My debugging message'.

Viewing Debugging messages

Now that we have a mechanism for writing debugging messages, the question is how do we view them?

There are several options.

DbMon

The simplest method of viewing debugging messages comes from DBMon.exe which is a Microsoft program available in several SDKs. You can download a copy here. It is a 6kb program and if it is running, debugging messages will be written to it. If it is not running, then the debugging messages are ignored. This allows you to use the same program (development or runtime) and only view messages when required. DBMon will display messages from any application that is producing debugging information, so Smalltalk MT messages are prefixed to distinguish them.

Note that if you right click on the DBMon window title, you can adjust the number of lines captured, the font sizes, window width etc. Using the system menu (top left hand icon), you can also mark text and copy it to another location.

Note: If  text is highlighted in DbMon, then all debugging output is frozen. That is your program will wait when it tries to output debugging information.

WinDbg

The next simplest method is to use Windbg which allows you to attach the debugger to a running program (either development or runtime). WinDbg is a Microsoft Debugging program that is available here. WinDbg will display all debugging messages from your application only in the command window. WinDbg has a number of other uses for debugging which I will discuss later.

Runtime exceptions

Finding a method selector

If your runtime encounters an unhandled exception, it will typically display something like (this behavior is fully programmable see below under Event Reporting):

An instance of "MyClass" did not understand the message "Symbol(16r1D24)"
The message was sent by an instance of "MyOtherClass"

By default, Smalltalk MT symbols are not included in a runtime image because they consume a lot of space. Hence only the symbol value can be displayed by the exception handler.

If this happens at a client site, you can determine the value of this symbol by loading the development environment and either use the Smalltalk code Symbol value: 16r1D24 or use the DumpViewer (on the toolbar) and on the Symbols tab, enter the symbol value 16r1D24. Either of these messages will display the method name associated with the symbol.

If you are still in development, you can simplify this procedure by including the symbol table in the runtime image. To do this, look at the Build Properties for you project (Project Browser->Options->Build Properties...). On the Options tab, tick the "Include full symbol table" check box. You will notice that your runtime is now considerably larger than before since it includes the full Smalltalk symbol table.

Using the Smalltalk MT runtime debugger

If you need more detailed information from your runtime exception, you can enable the runtime debugger. To do this, go to the Build Properties for your project (Project Browser->Options->Build Properties...). On the Options tab, select Debug as the Build mode. Notice that this automatically enables "Include full symbol table".

To allow the runtime debugger to run, access is needed to sources.bin (so the runtime debugger can get to the source) and to a resource DLL (image_rsrc.Dll) which you will find in the Smalltalk MT directory in Support\Debug.

On a runtime exception you will be presented with a Smalltalk runtime debugger window that allows you to examine the call stack and variable values and allows you to browse around in the source as through you were in the development image.

Using an external debugger for a runtime

If you need to debug in more detail (i.e. at assembler level) then you need to include some information for the external debugger to help you navigate. The simplest option is to go to the Build Properties for your project (Project Browser->Options->Build Properties...). On the Options tab, drop down the "Generate Debug Info" list box and select "Methods Only". You can use WinDbg to start your runtime, or you can attach WinDbg to your running application. When an exception happens, WinDbg will trap and allow you to look at the call stack, registers and memory.

Using an external debugger for the development image

Sometimes you may need to debug the development environment. You can include debug information for the development image by saving the image with Compress and "Generate COFF Symbol Section" both checked. You can then use WinDbg to trap development environment exceptions and locate the source of the problem.

Event reporting

By default, a Windows program will simply report an unhandled exception and will end the offending program. Smalltalk MT allows you to take several actions depending on your requirements.

First I will show the default behavior. On an Event Report (for example a Runtime Exception) you will get three message boxes. Two of these are from Smalltalk MT and one is from Windows.

Box 1

Box 2

Box 3 (Windows XP)

By default the Event reporting uses LOGMODE_MESSAGEBOX which enables Smalltalk MT to put up information message boxes. You can set the following options:

MessageBox setLogMode: LOGMODE_NONE

No Smalltalk MT message boxes will be shown. An example of this is when a project is being loaded. LOGMODE_NONE is enabled while the project is being loaded to avoid having message boxes popping up.

MessageBox setLogMode: LOGMODE_EVENT

In this case, the Event is reported to the Windows Event Application log. You will need to use the Windows Event Viewer to view these messages.

MessageBox setLogMode: LOGMODE_DEBUG

In this case, the Event is written to debug output (use DbMon or WinDbg) to view the messages.

Box 2 is enabled/disabled in the Image Property Settings. By default, Errors is enabled and this setting causes Box 2 to display. If you turn Errors off, Box 2 will not display.