RAD Studio 2010 Review #3: Debug Visualizers.

RADStudio 2010Guys, don’t forget that we’re talking about a pre-release beta. Everything can change till release. Also, all our gratitude for Embarcadero for allowing us to talk about these things.

…Once upon a time was a command line compiler. In text mode. You wrote the source in another editor. In text mode also. But the times changed. First, appeared the IDE. All together, way better. In the old text mode.  The notion of integrated debugger appeared. What a relief. But in the text mode. But the times changed. We got graphical GUIs. We got form designers. Graphical. But the debugger remained, basically the same. In the old text mode, even if the text was shown in a graphical GUI. But not anymore… Introducing the Debug Visualizers. As we all know, one of the vital part of a Debugger is the so-called Evaluator (or Evaluation Engine) which surfaces itself in the Watches, Local Vars, Evaluate / Modify window etc. Basically is that piece of code which ‘transforms’ the variable name typed in by us in the appropriate value.

In other words,  the Evaluator is responsible to ‘transform’ the text 'cMyFilePath' to ‘C:\Documents and Settings\FooUser\FooFile.txt’, showing the actual content of that variable.

As you remarked already, I use the word transform instead of perhaps a more appropriate term of evaluate. This is because it gives us the idea:

Hey, what if we can have more complex transformations of variables, not just simply evaluating their contents?

This is particularly useful when we speak about encoded data types like TDateTime complex data types like objects.

Usually, for different encoded data types (but not only) is very nice to have a simple Visualizer called in-line visualizer which in fact can be seen like a function to transform the encoded variable in a string with the appropriate human meaning. Of course, for TDateTime values this in-line visualizer would be based on DateTimeToStr function.

While the above is very handy for simple situations, a complex object cannot be displayed as a string and is necessary to open a Popup to display (ie. visualize) it. These are Popup Visualizers.

RAD Studio 2010 supports only one in-line visualizer / type (and if you’d ask me I don’t think that is really needed to support more – but of course is just my opinion).

But it can have multiple Popup Visualizers for a certain type. If a type has a Popup visualizer assigned to it, then a small icon appears next to the variable of that type. See for yourself bellow…

DebugVisualizers1

As you see, Delphi ships with some visualizers: one in-line for TDateTime types (in the green circle) and at least one Popup visualizer for TStringList types (the loupe icon in the red circle).

Pressing the icon, a popup menu appears showing us all the available visualizers for that type to choose from (in our case just one visualizer):

DebugVisualizers2

…and by choosing that visualizer it shows us the actual content of the TStringList instance:

DebugVisualizers3

How is implemented?

The Debugger Visualizers are implemented as Experts (hence anyone can write such things) using some new IOTA interfaces. For the interested ones, have a look at ToolsAPI.Pas located in ...\Source\ToolsAPI\.

The basic interfaces to look are:
IOTADebuggerVisualizer, IOTADebuggerVisualizerValueReplacer (this is for the in-line visualizer aka. Value Replacer), and IOTADebuggerVisualizerExternalViewerUpdater (this is for the Popup Visualizer).

Source code? (the eternal question…)

Of course! For the editions which include the VCL source code the source for the Visualizers is located in <RAD Studio Home>\source\Win32\Visualizers

I think that this opens a plethora of possibilities for debugging. We’ll come back after RAD Studio is released. But let me ask you a question:

How do you see possible enhancements of the debugger and / or ensuring code quality in the future? (Feel free to think and speak 🙂 )

16 thoughts on “RAD Studio 2010 Review #3: Debug Visualizers.

  1. I work a lot with Netbeans and a very useful feature is the ability to change a statement while debugging and to execute the new code without having to recompile all the code, but maybe it’s something limited to VM and JIT.

    • Actually I think something could be done with native compiled code too, the debugger could “patch” the in-memory imege of the executable placing a jmp instruction or the like and point it to the new compiled code adding the instruction to return to normal flow – of course I guess using a VM is much easier.

    • @Paolo Biondi
      Let me try to understand what you want. During the debugging of your program you realise that some calculation is wrong. So you fix the calculation so the rest of the calculations can run right. But after changing the calculation/behaviour of the program I would want to no longer continue with the results of the bad calculations – so I would restart the program.

      I find that it is very rare cases that you can accept that your program has changed during its execution. You could never reproduce such a run.

      In short, I see little value from such a feature, but lots of complexity with it.

      • I agree. Additionally, as Delphi compiler is lightning fast – it’s not such a PITA to recompile app when required.

  2. Hopefully they decide to add a few visualizers for basic graphics formats supported by the IDE as well – Not a really hard thing to do.

  3. I like this a lot.

    The inline display for TStringList is a little sparse. Do you know if a type have both an inline and popup visualizer? It might be nice to show how many elements there are at a glance and still have the popup for details.

    • For this release, there is no inline visualizer for TStrings. Fortunately, writing such a visualizer is somewhat ‘doable’… 🙂

      Also, I want to stress that I agree with your comments.

      • That’s what I’m kind of asking. Is it possible to combine an inline visualizer that I write myself with the existing popup one.

  4. At first Visualizers are good stuff, thanks. The times when I am speculate what datetime 40032,436849 means are ending. 🙂

    When there is only one Popup Visualizers, please open it directly, because everybody will hate to choose one visualizer from list with one entry. That is nothing. Check this out. I define a default Popup Visualizer which is open when I click the icon and from this view I can choose one of the others.

  5. This is a great feature and makes a debug-only variable obsolete. I add a string variable to each of my many and complex classes, this variable contains a formatted string with all properties as text values. Because it is a simple string variable it can be viewed in the debugger. But of course other variable types are not observable in this way.
    I hope this feature is tested well and made easy to use because I don’t want to have side effects in my code due to the extra source overhead. Consider a bug in the application itself that only appears in debugging mode because of this feature. Horror.

  6. Pingback: Личная записная

  7. Pingback: Paweł Głowacki : RAD Studio 2010 - Object Inspector "verbs" area

  8. I am trying to make debugger Visualizer for Dataset classes for Delphi 2010, using StringListVisualizer as a reference, but I can’t get
    viewed object with IOTAThread.Evaluate.

    I tried casting value returned from Evaluate in ResultAddr to TDataset but that is not working, in variable Exppresion is dataset variable
    name and EvalRes is returne as erOK, but when I try to use Result access violation occures.

    Is this possible ? I mean is it possible to get real live object with IOTAThread.Evaluate not just a string like StringList Visualizer does.

    Here is the code (this is a slightly modified code from StringList visualizer) :

    function TDatasetViewerFrame.GetDataset(Expression: string): TDataset;
    var
    CurProcess: IOTAProcess;
    CurThread: IOTAThread;
    ResultStr: array[0..4095] of Char;
    CanModify: Boolean;
    ResultAddr, ResultSize, ResultVal: LongWord;
    EvalRes: TOTAEvaluateResult;
    DebugSvcs: IOTADebuggerServices;
    begin
    begin
    Result := nil;
    if Supports(BorlandIDEServices, IOTADebuggerServices, DebugSvcs) then
    CurProcess := DebugSvcs.CurrentProcess;

    if CurProcess nil then
    begin
    CurThread := CurProcess.CurrentThread;
    if CurThread nil then
    begin
    EvalRes := CurThread.Evaluate(Expression, @ResultStr, Length(ResultStr), CanModify, eseAll, ”, ResultAddr, ResultSize, ResultVal,
    ”, 0);

    case EvalRes of
    erOK:
    Result := TDataset(ResultAddr); // Result is shown as Inaccessible value in debugger

    … cut

    • To anwser to myself, Debug Visualizers are siriusly limited in this version, It’s not possible to get any value form debugger other than string. This means visualisers are possible ONLY for objects / types that can evaluate to string. And Visualizers only work for current class not for descendants, eg. If I declare

      TMyStringList = class(TStringList);

      for objects of type TMyStringList the loupe icon will NOT be shown and TStringList visualizer won’t work for this class.

      Let’s hope that this would be better in the next version.

      • There are two kinds of visualizers:
        – Replace: which changes the evaluated value with any string of your choice.
        – Popup: Here you can display a visualizer which isn’t evaluate to string. You can build a popup form which will show for example a color. Yes, of course, at some moment in time the color must be string (ie. $00A0BBFF) but this doesn’t matter to much in our discussion.

        Also, IIRC you can define a visualizer to act also for descendants.

        HTH

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s