7.2 An Example Usage

This section assumes the record program has been compiled as described in the previous section. Running record results in a runtime error:

> cd myDir      
> record        
# BETA execution aborted: Reference is none     
# Look at 'record.dump'

If you have the Mjolner tool running, you can run record by choosing "Run record" from "Compile/Run" menu.

Now let's use Valhalla to locate the cause of the error. Start Valhalla by typing choosing "Debug Record"

Valhalla will initialize and open the Valhalla Universe as shown [4] in .

Figure 41

[5kb 683x457 GIF]

If the record program took any commandline arguments, we could specify these using the command-line editor. Choose "Command-line" from the "Edit" menu in the Valhalla Universe.

Figure 42

[2kb 220x150 GIF]

The Valhalla Universe defines a number of menus. Most commands in these menus operate on the state of the debugged process, or enables control over the debugger process.

The middle pane of the Valhalla Universe contains a view area in which the different local views will be displayed.

Finally the bottom pane contains three areas: the Process Info Area, the Valhalla Info Area, and the Buttons Area.

In the Process Info area, you will see different messages related to the debugged process. In , you see the message: No Process, indication that no process is being debugged at this point.

In the Valhalla Info Area, you will find different messages related to the operation of Valhalla (status messages, error messages, etc.). In , no Valhalla messages are displayed.

In the Buttons areas, you find a number of buttons, which are short-cuts to often used commands, also found in the menus of the Valhalla Universe.

After we now have presented the Valhalla Universe, we continue the record example. When Valhalla has finished initializing, the program code for the debugged program (debuggee) is displayed in the sourcebrowser. Note that the program-descriptor is shown. If you had any other code opened you can find back to it using the "History"-menu.

We are now ready to start execution of the record application. We do this by pressing the Go button in the Buttons Area. The application will now begin execution, and since there in this case is a runtime error, the debugged process will not complete. Since the application is being debugged, the application does not terminate as usual, but will signal the error to Valhalla.

Note that a new code view is now visible in the sourcebrowser. This new code view displays the code being executed at the time of the runtime error, and highlights the exact source code that gave rise to the runtime error.

The name of the code view opened is Fragment: lib and the pattern in the source code is newBook, implying that the newBook pattern is defined in a fragment, called lib. From here, you can now use the semantic browsing facilities described in the Mjølner Tool manuals ([MIA 99-39], [MIA 99-40], [MIA 99-34]) to find the definitions of the different names in the displayed source code. If the semantic links refer to source code, not in the current code view, new code views are created, displaying the proper source code (similar to Open Separate in Sif). If, during browsing, you forget what imperative caused the error, or cannot find the window containing that imperative, just press the Code button, and Valhalla will raise (and wriggle) the window with the offending imperative selected.

A number of other informations about program state at time of error would be useful in order to decide what caused the error:

In the following sections we will consider how to obtain these informations.

7.2.1 Inspecting object state

Above we found that Valhalla automatically displayed the source code containing the offending imperative. Usually, in order to determine the cause of the error, one has to consider the state of the objects in the executable to understand what caused the error. To browse the state of the objects, Valhalla implements so-called object views.

The immediately most interesting object, related to the error is the so-called Current Object, which is the object that executed the offending imperative. We can gain access to the current object by pressing the Object button in the Buttons Area. This will result in an object view being displayed in the Universe. This object view will display the state of the Current Object at the time of the error.

More generally, whenever the debugged process is stopped, pressing the Object button in the Buttons Area of the Valhalla Universe opens an object view displaying the current object if already open in the Universe, the object view will be raised (and wriggled). If we press the Object button, we get the following contents of the Universe:

Figure 43

[7kb 712x397 GIF]

From the object view in figure 3, we see that the current object at time of error was an instance of the pattern NewBook. The state of the object is displayed in the window. The Rec attribute is a reference to an object and is therefore described only by the name of its pattern, followed by ~ and a number. If we double-click the line Rec: ^Book~3, a new object view is opened, displaying the state of the object referred to by Rec (as shown in figure 4):

Figure 44

[8kb 712x397 GIF]

As it can be seen, the author attribute of Rec is NONE. This is actually the reason for the runtime error in record. As you probably remember, the failing imperative was A->Rec.Author and because Rec.author is NONE, this results in a runtime error. If you do not remember, simply press the Code button in the Buttons Area of the Universe.

Since author is a dynamic reference to a Text object, we could correct the error by changing author to become a static instance of Text (exchanging ^ with @).

Eventhough we have now found the source of error, there is still a number of Valhalla features that have not yet been demonstrated. As a consequence we just continue this tutorial to introduce you to more of the Valhalla functionality.

Some attributes are shown contracted (shown by the ... ). These ... indicate that these objects are complex objects, with inner structure. You can see the inner structure (and state) by double clicking on the attribute. If we do this on e.g. the A attribute, we get the following screen:

Figure 45

[9kb 712x397 GIF]

Note, that in contrast to when we followed the Rec attribute in , no new object view is opened, but the state of the A attribute is shown inline. This is due to the fact, that A is a static object, whereas Rec is a dynamic object reference.

Object views are updated every time the program stops by hitting a breakpoint, receiving a signal or in case of a runtime error.

7.2.2 Inspecting the call chain

Now we know where and why the error happened. But how did we get there? To answer this question we use the stack view: We can get a stack view by pressing the Stack button in the Button Area.

The stack view shows the process stack at time of error. Each line in the stack view refers to a stack frame, with the most recent as the top-most line:

Figure 46

[8kb 712x397 GIF]

By double-clicking on the lines in the stack view, code views are opened, displaying the code related with this stack frame (with the active imperative selected). By holding the right mouse button down on a line, you get a small menu from where you can create object views, displaying the state of the corresponding stack frame.

In the bottom of the stack we can see that there is only one component present. This is the main component corresponding to the main program pattern, which is allways present.

7.2.3 Rerunning the program

If it during a debugging session becomes necessary to restart the debugged process (e.g. to try to trace the location of the error after having inserted some breakpoints), we can rerun the debugged process by pressing the Rerun button in the Buttons Area. The debugged process will then be reinitialized and prepared to start from the beginning again. All existing program state is cleared by the rerun, but existing breakpoints are maintained.

7.2.4 Setting a Breakpoint

Until now, Valhalla has decided when to interrupt the debugged process, doing so because of a 'Reference is NONE' error. We have not yet seen an example of controlling the program execution in greater detail. To do this we are now going to restart the debugged process and trace the program flow until time of error

We press the Rerun button, and Valhalla now restarts the process and makes it ready to be restarted [5].

We now examine the code view, locating the invocation of the erroneous NewBook pattern. We now want to make the process continue execution until it is about to execute NewBook. We can do this by setting a breakpoint immediately before the invocation.

We click at the BETA imperative containing the generation and execution of a NewBook object. Then select Set Breakpoint from the Breakpoints menu in the Universe. An breakpoint marker (>>1>>) appears in front of the imperative to mark the presence of a breakpoint (the 1 indicates that this is the first breakpoint). You can also set the breakpoint by using the popup-menu associated with the right mouse button. The process will thus be interrupted just before this imperative is about to be executed. Figure 7 displays the look of the code view at this point.

Figure 47

[22kb 791x566 GIF]

Having set the breakpoint we make the debugged process begin execution by pressing the Go button. The process now runs until the breakpoint is hit. Then Valhalla updates all open code, stack and object views to display the current state of the debugged process.

Alternatively, we could have selected the Step Over button a number of times. Step Over executes the imperatives one by one, returning control to Valhalla after each imperative. This would bring the debugged process to exactly the same imperative, but by executing an imperative at the time in the PROGRAM fragment [6].

Now we would like to continue until the first imperative executed by NewBook.

From here we might want to trace the execution more closely. We can do this by using the Step button. Step is a single step facility, which executes one single BETA imperative at a time. This implies, that Step Over executed entire patterns in a single step, since Step Over is intuitively single stepping at the imperative level of the visible code in the code view, whereas Step will stop execution e.g. immediately after a pattern invocation have been initiated, setting a breakpoint before the first imperative in the invoked pattern.

If we now press the Step button repeatedly, we can now follow the execution closely, until we reach the point immediately before the offending imperative.

7.2.5 The End

You have now concluded a tour of the most important Valhalla facilities. To get a more detailed description of these facilities as well as others not covered in this tutorial, please consult the reference manual.


[4] Screen dumps shown in the tutorial shows the views as they would have been if you had not copied the example program to a directory of your own, but simply compiled them in the ~beta/debugger/demo directory
[5] All breakpoints set before rerunning the program will continue being set
[6] Step Over sets a breakpoint at the imperative following the current imperative in the current pattern and thus skips procedure calls that might be embedded in the current imperative


Mjolner Integrated Development Tool - Tutorial
© 1991-2002 Mjølner Informatics
[Modified: Tuesday September 4th 2001 at 0:07]