The debugger is activated in the following cases:
The reference file:
In order to analyze the data fully, reference files must exist for each of the modules to be examined.
A reference file for a module is generated by the compiler if the option "-REFERENCE" is
specified (see "Compiler", section 1.2).
The debugger expects this file to have the name "<module name>.MREF".
The symbol file:
Since the format of a symbol file is the same as that of a reference file, the debugger can use
a module's symbol file instead its reference file if no reference file is available. In such cases
however, only entry routines and exported variables can be interpreted. This feature is particularly
handy if an error occurs in a module for which you do not have a reference file. You can access
information specific to a procedure-call in a library module in this way for example, so as to see if
there is an error in the actual parameters.
The source file:
The debugger can associate the program counter with a line of source code. It therefore also opens
the IMPLEMENTATION MODULE's source file. If generic modules are refined additionally all generic
sources are opened, more than once if more refinements of the same generic module is done. All
source files are displayed as one large source file (alike the listing file). The setting and
clearing of breakpoints is done in this program-source window. Note that only the actual original
source can be worked on in this way—the listing file cannot be used.
The debugger expects this file to have the name "<module name>.MOD" respectively
"<module name>.GMO".
The path file:
The path file is a text file created by the programmer. It contains the names of all the
folders in which the debugger should look for the above files. Each line of this file starts
with an identifying letter. Immediately after this letter follows the name of exactly one folder.
The initial letter indicates what kind of file should be looked for in the folder specified:
"R" means reference and symbol files, and "M" means source files (with
the extension ".MOD" / ".GMO"). The folder names must not be enclosed
in quotation marks even if they contain special characters. Furthermore each folder name
must end in a slash. The debugger looks for the path file under the name "Debug.DAT"
in the current working folder. It does this when it is first activated.
A path in the path file may be specified in two ways. If the path starts with a slash, it
is treated as an absolute path. Otherwise it is interpreted as a path relative to the
location where the path file resides. This is useful especially for applications where
the current working directory is "/".
Example:
M/System/User/Wiedemann/Entwicklung/M2/Library/RTS/ M/System/User/Wiedemann/Entwicklung/M2/Library/StdLibMods/ R/System/User/Wiedemann/Entwicklung/M2/Library/REFs/ R./Compiler/Ref/ M./Compiler/Common/ M./Compiler/Pass1/ M./Compiler/Pass2/ M./Compiler/Pass3/ M./Compiler/Pass4/ M./Compiler/Pass4Mac/ M./Compiler/Pass4C/ M./Compiler/Pass4PPC/ M./Compiler/Listing/ M./Compiler/Symfiles/Notes:
![]() | ![]() | |
Error dialog ppc | Error dialog Intel |
The procedures are numbered in the order of their declaration. First of all the exported procedures declared in the definition module are numbered, starting at 1 (one). After that the procedures defined in the implementation module (which are not exported) are assigned numbers in the order of their appearance in the source code. The initialization part of a module is always assigned the number 0 (zero).
Keyboard equivalents for the buttons are shown in parentheses in what follows.
With the buttons "up" (up arrow) and "down" (down arrow) you can find out about the routine dynamically preceding or succeeding (respectively) the routine shown.
The button "Abort" (A) ends the program immediately, without activating the Modula-2 debugger, by calling "_exit".
The "Resume" button (R) causes the program to resume execution. The button is only enabled if no serious error has occurred.
"Term" (T) initiates or continues the Modula-2 termination process (cf. "Compiler", section 2.6). This button has exactly the same effect as a call to "HALT" at this point in the program.
"Handler" (H) activates the relevant exception handler (cf. "Compiler," section 2.7). If "BREAK" was called or a breakpoint has been encountered, this button is disabled.
Finally "M2 Debugger" (D) brings Modula-2's symbolic debugger into action. This button is only active if the debugger was included when the program was linked. After clicking the button, six of the debugger's windows appear. Then the debugger reads the file "Debug.DAT" in the current working directory and interprets it as path file. If the file "Debug.DAT" does not exist in this place, a dialog box appears asking "File for default search?" and containing "OK" and "Cancel" buttons. If "OK" is clicked the system's standard "get file" dialog appears enabling the path file to be located and selected. If "Cancel" is clicked or the file-selection dialog is itself cancelled, the debugger is only able to look in the current directory for necessary files.
If a file cannot be found even with the help of the path file, a message appears that can be dismissed either with "OK" or with "Cancel". If dismissed with "OK" the Macintosh "get file" dialog appears so that a file can be selected as source / reference (or symbol) file. In this way files can also be used which do not conform to the usual naming convention that a file's name excluding its extension is also the name of the module itself. Dismissing with "Cancel" means (as far as the debugger is concerned) that the file does not exist.
Holding the command and option keys down during program launch forces a breakpoint at the beginning of program execution. This breakpoint is set at the beginning of the initialization part of the main program, after all imported modules have been initialized. From there, breakpoints can easily be set in other parts of the program.
By pressing "shift", "command", and "option" key simultaneously at program startup, a breakpoint can be forced before the initialization of the first module. This breakpoint may be used to find bugs in the initialization parts. However, as initialization is not yet done, not all modules may be accessible at that point.
If a file (either source or reference file) cannot be found even with the help of the path file, a message appears in the terminal window and allows either to specify path and name for this file or to abort.
By selecting an item in one of the various windows and then choosing an appropriate menu command or by double-clicking a selectable item (applications) resp. pressing the right arrow key (tools), information corresponding to that item is displayed in the other windows. Columns in the windows adapt in width automatically according to the size of the window. If a window is too narrow to display all the data in full, names are truncated where necessary, the missing parts being indicated by ellipses.
The up and down arrow keys may be used for scrolling in all windows (if applicable).
For applications, all the windows can be closed, moved and resized. The configuration of the windows is
saved between calls to the debugger (within the one program execution).
For tools, the active window is highlighted (background color yellow, foreground color blue). The selected
line is displayed with cyan background and red foreground. Besides using
the menu, the active window may be changed by using the <TAB> key.
In what follows the function of the windows and their interdependencies are described.
An example debugger-window arrangement:
For applications, each of these items can be selected by clicking with the mouse.
If you select the module name, the commands "Open Source for <module name>",
"Open Data_1 for <module name>" and "Open Data_2 for <module name>"
appear in the "Windows" menu. Selecting one of these commands will display the source code
or variables of the chosen module in the relevant window accordingly. The other windows remain unchanged.
Double clicking on a module name fills the two windows "Source" and "Data_2" with
applicable information.
If the address is selected, the command "Display at $<address>" can be used to display
the corresponding part of memory displayed in the Memory window. Double clicking on the address
achieves the same thing faster.
For tools, each line can be selected up and down arrow. For the active line, the commands
"Open Source for <module name>",
"Open Data_1 for <module name>" and "Open Data_2 for <module name>"
appear in the "Windows" menu. Selecting one of these commands will display the source code
or variables of the chosen module in the relevant window accordingly. The other windows remain unchanged.
Pressing the right arrow key fills the two windows "Source" and "Data_2" with
applicable information for the module in the active line.
The command "Display at $<address>" can be used to display the corresponding part of
memory displayed in the Memory window.
The modules list ist sorted alphabetically. Typing a key selects the first module with the given starting character.
For applications, if a procedure name is selected, the commands "Open Source for <module name>",
"OpenData_1 for <procedure name>" and "Open Data_2 for <procedure name>" appear
in the "Windows" menu analogous to when a module name is selected. After choosing one of these
menu items the source code or variables of this procedure are displayed in the respective window accordingly.
A double click on a procedure name correspondingly results in the two windows "Source" and
"Data_1" (not "Data_2"!) being filled with the relevant information.
If one of the addresses to the right or a procedure name is selected, the corresponding part of memory can be
displayed in the Memory window by choosing the menu item "Display at $<address>" or by
double clicking on the address. When clicking the relative program address, the selected part of memory
is automatically disassembled and shown in the appropriate instruction format.
For tools, each line can be selected up and down arrow. For the active line, the commands "Open Source for <module name>", "Open Data_1 for <procedure name>" and "Open Data_2 for <procedure name>" appear in the "Windows" menu analogous to when a module name is selected. After choosing one of these menu items the source code or variables of this procedure are displayed in the respective window accordingly. Pressing the right arrow key fills in the two windows "Source" and "Data_1" (not "Data_2"!) with the relevant information for the procedure in the active line.
Opening a variable of type "COROUTINE" (by double click resp. right arrow key) switches the display to showing the procedure-call chain associated with the coroutine referred to by this variable.
Activating a procedure name will display the procedure's local variables in "Data_1"; activating a module name will display the module's global variables in "Data_2".
To the right of each variable (or field) name is shown the following:
Opening a variable of type "COROUTINE" (by double click resp. right arrow key) switches the procedure window's display to showing the procedure-call chain associated with the coroutine referred to by this variable.
The value of a non structured variable may be changed by double clicking on it (for applications) or pressing the right arrow key (for tools) (cf. 1.5.4 Options menu).
Address values and values of system types are shown in hexadecimal, the values of all other types according to their types.
In the line of text immediately below each Data window's title bar is shown the name of the
procedure/module or variable/field/element to which the variables or fields/elements respectively
visible in the rest of the window actually belong. This name can become extremely long, in particular
for example when examining a linked list (in which the dereferencing of pointer variables occurs repeatedly).
For applications, the arrows at each end of (the visible part of) the name can be used to scroll it to the
left or right. By double clicking on any part of the name the display can be snapped back to showing the data
corresponding to the name up to that point.
For tools, the left arrow key is used for stepping back the list.
For tools, the memory area of a variable may be displayed in the Memory window by choosing the menu item "Display at $<address>". For applications this may be achieved by either double clicking on the address of a variable or by selecting the address and then choosing the menu item "Display at $<address>".
The value of a variable may also be changed by selecting the address of a variable and then choosing the menu item "Set value at <address>…" (Options menu). This is used especially for changing pointer variables, as double clicking / right arrow on a pointer variable will dereference it.
The Source window is also designed for setting and clearing breakpoints. In version 9.0, the use of breakpoints is not available, as this part needs a full redesign of the debugger.
What section of memory is shown can be regulated by double-clicks / selection in the Modules, Procedures, Data_1 and Data_2 windows, as well as by the menu items "Address" and "Display Selection" from the "Memory" menu and of course by the use of the scroll bar. The remaining items in the "Memory" menu can be used to choose how it should be displayed.
In all display formats except "Ascii", "Instruction" and the floating point formats four consecutive bytes of memory contents can be selected as an address for the "Display Selection" command or for double clicking. This is particularly convenient when dealing with pointers or handles. This selection may also be used to change memory locations by "Set value at <address> …". The selection is always interpreted as an "ADDRESS", the input is required for four bytes in hexadecimal notation.
It is up to the user to ensure that a reasonable value is specified for the start address of the memory to be displayed. If the address entered falls outside the range of the memory actually available or addresses a memory mapped I/O device then only zeros are displayed. It is therefore recommended that the section of memory to be examined only be selected by double clicking on an address in the Modules or Procedures window or one of the Data windows
CTR | Count Register |
LR | Link Register |
PC | Program Counter |
CR | Condition Register |
XER | Integer Exception Register |
MSR | Machine State Register |
FPSCR | Floating Point State- and Control Register |
VRSave | Vector Save Register |
VSCR | Vector State and Control Register |
SP | Stack Pointer, also r1 |
r30 | Static Link, if an inner procedure accesses the variables of surrounding procedures |
r31 | Global Pointer, if a procedures accesses global variables of its module. |
The AltiVec registers are displayed always, there value is meaningful only on computers that support the AltiVec instruction set.
EIP | Instruction Pointer |
FLAG | Flag Register |
Trap | Trap Number |
Err | Error Number |
Addr | Faulting Address |
FPCONT | Floating Point Control Register |
FPSTATUS | Floating Point State Register |
FPTAG | Floating Point Tag Register |
SP | Stack Pointer, also esp |
FP | Frame Pointer, also ebp |
esi | SELF Pointer in Methods, Static Link, if an inner procedure accesses the variables of surrounding procedures |
edi | Global Pointer, if a procedures accesses global variables of its module. |
These lines are followed by the old FPU registers st0 through st7 used for LONGDOUBLE arithmetic and the xmm-registers xmm0 through xmm7 used for REAL and LONGREAL arithmetic.
RIP | Instruction Pointer |
FLAG | Flag Register |
Trap | Trap Number |
Err | Error Number |
Addr | Faulting Address |
FPCONT | Floating Point Control Register |
FPSTATUS | Floating Point State Register |
FPTAG | Floating Point Tag Register |
SP | Stack Pointer, also rsp |
FP | Frame Pointer, also rbp |
r13 | Static Link, if an inner procedure accesses the variables of surrounding procedures |
r14 | SELF Pointer in Methods and their inner procedures. |
r15 | Global Pointer, if a procedures accesses global variables of its module. |
These lines are followed by the old FPU registers st0 through st7 used for LONGDOUBLE arithmetic and the xmm-registers xmm0 through xmm7 used for REAL and LONGERAL arithmetic.
For tools a special menu bar mechanism is available. The menu bar is shown in the first line of the terminal window.
Each menu may be accessed by holding down the <CTRL>-key and pressing the underlined character. The menu
drops down. Navigation ist done by the four arrow keys. Pressing the <ENTER>-key chooses the selected menu item.
Menu shortcuts are activated by holding down <SHIFT> and pressing the shortcut key.
The windows behind the menus are restored after choosing a menu item.
Please note that not all menu items are applicable when debugging a command line tool.
The menu commands made available in this way are described briefly below.
Continue Application/Tool
This command allows resumption of execution after a breakpoint or a minor error.
Single Step
The program is continued up to the next line of Modula-2 code.
(ATTENTION: not implemented in V9.4)
Single Step Skip Calls
The program is continued up to the next line of Modula-2 code, subroutine calls are skipped.
(ATTENTION: not implemented in V9.4)
Terminate
Has the same effect as a call to "HALT" at this point. Modula-2's termination process is started
or continued (cf. "Compiler", section 2.6). This is the menu item that
should normally be used to quit a program from the debugger.
Exception Handler
Continues the program with the currently active exception handler (cf.
"Compiler" section 2.7). This item is only available if the
debugger was triggered by a genuine exception condition (which does not include calls to "BREAK",
breakpoints or "single steps").
Exit Application
This command can be used to end the program.
This "emergency exit" should only be used if ending the program with "Terminate" no
longer seems advisable because of inconsistent data.
Stack Windows
Displays all windows, arranging them staggered on the screen in a stack.
The remaining commands are for opening and activating the various windows individually. They can also be used to reassign the contents of the Source window and the Data windows.
Display Selection / at $…
A selected address can be made the start address using this command.
The remaining commands are for setting the memory window's display format.
Call Options …
This puts up a dialog in which the conditions under which the debugger should be called can be specified.
In the upper part of the window the exception conditions can be selected for which the debugger should be activated before an exception handler is called. Default: all except user-defined.
The lower pair of radio buttons are for specifying whether the debugger should be activated (again) if an exception was not handled by any exception handler at all. The default is that it should not.
If the check box "skip dialog" is marked the debugger is activated at breakpoints directly, without intervening error dialog. This is convenient if the debugger is to be used at every breakpoint. Default: off (i.e. dialog not skipped).
Delete All Breaks
Clears all breakpoints.
Show Next Break
Brings the next breakpoint into view in the Source window. By issuing this command repeatedly all
breakpoints set can be displayed one after the other.
Crashed Process
Displays in the debugger the procedure-call chain of the coroutine which caused the debugger activation.
This makes it possible when analyzing parallel coroutines to switch back to the active coroutine even
if its process descriptor is not stored in any variable.
Main Process
Displays in the debugger the procedure-call chain of the main program.
Set Value at …
This item allows to change the value of a selected none structured variable (data windows) or of a
selected memory location (memory window).
A dialog for input of the new value pops up; for enumeration types a list of all possible values is displayed to select from. Input is checked for correctness (e. g. format, range), wrong input is rejected. For subrange types an additional range check is performed. If this check fails, the value may be set nevertheless, but is truncated to the available data space.
For SET variables, short sets (up to four bytes) may be changed by one input, longer sets may be changed byte by byte (as they are displayed in the data windows). Structured variables may be changed element by element.
table of contents (utilities) | start page | chapter 2 (utilities) |