Delphi 2009: Couple of hints on Debugging

As a result of my last seminar, I would like to present some neat facts about the debugger and the interaction of the Delphi IDE with the debugger.

Our lab project will be a simple VCL Forms Application created using File / New … / VCL Forms Application.

On the dialog being shown as a result of this, we will drop a TButton and double-click it in order to implement the OnClick event.

The dialog should look like this:

Form

In the OnClick event we will implement some very insightful piece of Delphi code:

source code

The code checks the Sender reference if it has been instantiated from TButton and shows a message if true. Wonderful.

Now to debugging.

Breakpoints are great to start investigating variable values at a certain line in code. Delphi makes it easy to set breakpoints by pressing F5 (default layout) or clicking in the gutter on the left side of the code. Let’s add a breakpoint in line 28 (referring to the line numbering above):

image

When running the application and clicking the button, the debugger stops at the location we wanted it to, however, we are unable to gain any useful information without additional work.

First of all, the value of Sender is displayed as "()"  and the value of "Self" is denoted as inaccessible. This means that the compiler has optimized our code and this is something one can switch off in the project settings. Thus, cancel debugging by pressing Ctrl+F2 and select the menu items Project / Options…

image

In the "Delphi Compiler" section, select the item named "Compiler" and have a look at the "Code generation" group.

You will find the item named "Optimization". Set this to "false" and it will be much easier to debug your applications. Performance will be worse, but while developing applications it might be more helpful to be able to debug easily.

Furthermore, a lot of Delphi developers always complain that they get redirected to the CPU view showing Assembler code when they try to step into VCL code. CodeGear deploys the Delphi VCL and a lot of other things with source code, so one should be able to step into it, don’t you think?

A simple switch will make this possible: In the "Debugging" group on the same options page mentioned above, set "Use debug .dcus" to true and rebuild. Let me emphasize: reBUILD. A simple compile will not do the trick if you have already compiled your application and change the setting afterwards.

Let us rebuild the application, run it with debugging and click the button. We will find out that now we get a lot of information about "self". Great!

However, Sender is still displayed as (). If we evaluate the value using Run / Evaluate or simply press Ctrl+F7, we get the same thing. If we type TButton( Sender ) however, we get the information we desire.

So, it is good to remember that Sender is being passed as TObject and the debugger tries not to get into any trouble. It accesses the variable reference with this exact type and thus there is no information to display. You as the developer have to do the thinking and type-cast it manually to TButton.

One final note. The result displayed by the evaluation dialog is not very nice to read:

image

Click on the Inspect button in order to get an Object Inspector-like view:

image

Be aware that you only get this view to inspect Sender if you use the expression TButton(Sender) to type-cast it.

Hopefully this blog entry gave some insight into the awesome debugging features of Delphi. Not that they were unique to this IDE, but I found out that many people do not know about these informative tools included in the product. So, one does not have to buy third party tools to get good debugging results.