Ide/Debugger
IDE |
---|
Visual Prolog Debugger
Visual Prolog Debugger is a powerful tool for finding errors in programs. Sometimes correcting errors in programs takes about 90% of the total development time. This proves that good tools for debugging are very important.
Visual Prolog Debugger can debug MS Windows 32/64-bit Graphical User Interface and Console applications and DLLs.
Visual Prolog Debugger provides ability to trace program execution. In the debugger one can set breakpoints, step through the source code (with viewing traced code both on Prolog and disassembler levels). The debugger allows inspecting variables used in the currently traced clause, viewing and retracting facts, viewing memory dumps, viewing the stack of predicate calls, viewing breakpoints inserted into the program, viewing registers, etc.
Visual Prolog Debugger is the IDE tool, which can be run with the Debug | Run menu command, with the F5 hot key, or with the toolbar button.
Generation of Debugging Information
Generation of the information for Visual Prolog Debugger is controlled by copmiler's option [..\Command_Line_Tools\Command_Line_.htm#DEBug /debug:full]. By default, the Visual Prolog IDE always generates debugging information while compiling project modules.
Starting Visual Prolog Debugger
When you start Visual Prolog Debugger (with the Debug | Run menu command, or with the F5 hot key, or with the toolbar button), then the IDE builds (if it is needed) the project, runs the target executable under the debugger, and breaks the program execution at the entry point of the goal section:
If in the Run Arguments edit control (in the Build Options tab of the Project Settings dialog) you have specified a string with command line arguments, then this string is passed to the program.
Debug Menu Commands
The Debug menu is used to control execution of the program being debugged.
- Run (F5)
- This command continues running the application. Issuing this command, when the IDE does not debug an application, builds (if needed) the application and starts its execution under the debugger. This command is often used in conjunction with setting of breakpoints.
- Run Skipping Soft Breakpoints (Ctrl+Shift+F10)
- This command continues running the application without breaks at Soft Breakpoint (see [Breakpoints_Window.htm Breakpoints Window] for more details).
- Stop Debugging (Shift+F5)
- This command stops the program execution. The IDE becomes active in the ordinary mode.
- Break Program
- When a program is executed (the program instructions are executed and the debugger is waiting till the program stops and returns control to the debugger), then with this command it is possible to break the program execution and to return control to the debugger. Then it is possible to inspect the call stack to see what the program is actually doing or to set a breakpoint where to catch the execution. Notice that this command is disabled while the debugger is active (when the program instructions are not executed).
- Restart
- This command restarts the application execution under the debugger.
- Attach process...
- It commands the debugger to attach to a process.
- Step Over (F10)
- It instructs the debugger to execute the next line of code. If the line contains a predicate call, Step Over executes the entire predicate, then halts at the first line outside the predicate.
If this command is used, then when you reach a predicate call, the predicate is executed without stepping through the predicate clauses (without entering into source code of the predicate).
Use Step Over if you want to avoid stepping into predicates.
- Step Into (F11)
- Step Into and Step Over differ in only one aspect — how they handle predicate calls.
- Step Into instructs the debugger to execute the next line of code.
- If the line contains a predicate call, Step Into executes only the call itself, then halts at the first line of code inside the predicate.
Step Into if you want entering into clauses of each called predicate.
- Step out of (Shift+F11)
- This command accomplishes execution of clauses of the currently executing predicate and calls the next predicate.
- Run to Cursor (CTRL+F10)
- It commands the debugger to run the application until it reaches the location where the cursor is set. This location can be both in Visual Prolog source code or in Disassembly window.
Place the cursor on a line and activate this command; the application will start execution until the line pointed by the cursor (if it can come to this predicate call). The Instruction Pointer will point to this line.
- Go to Executing Predicate Source (Ctrl+E)
- If you have moved in the program source windows and have lost the Instruction Pointer, then you may execute this command. It sets the cursor to the line containing the currently executing predicate (pointed by the Instruction Pointer).
- Break on Exception
- When this option is checked ON and if an exception occurs, then execution of program is stopped. Then you will be able to use the Run Stack window to locate your predicate in which the exception occurs. See how to Use Break on Exception for more information.
- Toggle Breakpoint (F9)
- Using this command you can set a breakpoint to any executable line in program source files.
- Remove All Breakpoints
- This command removes all previously set breakpoints.
How to Use Break on Exception
Some times, it is difficult to locate which your source code predicate generates an exception. In such situation the Break on Exception option can be helpful.
Start to debug your program. When its execution will be close to the expected exception, turn ON the Break on Exception option. (It can be inconvenient to turn the Break on Exception option from the begin of the debugger execution since this can bother you with some otherwise masked exceptions.)
When an exception occurs, Debugger catches it and execution of a debugged program is stopped.
Then you will be able to use the Run Stack window to locate the predicate in which the exception occurs and to inspect the sequence of calls which lead the exception. The topmost in the Run Stack window line corresponds to the last executed predicate. You can double click a line in this window to inspect a clause of the correspondent predicate. If there are no available sources for the Run Stack window entry, the Debugger will show the machine instructions in the Disassembler window.
Debugger Views
Several debugger windows can be opened from the View menu:
The windows, which can be used in the debugger (debugger views), are:
- Run Stack (CTRL+Alt+C)
- Variables for Current Clause (CTRL+Alt+V)
- Facts (CTRL+Alt+F)
- BreakPoints (CTRL+Alt+B)
- Threads (CTRL+Alt+H)]
- [Modules_Window.htm Modules ]
- Disassembly (CTRL+Alt+D)]
- [Registers_Window.htm Registers (CTRL+Alt+G)]
- [Memory_window.htm Memory Dump (CTRL+Alt+M)]
Also the following two windows, which are not only debugger windows (debugger views), can also be used while debugging:
Project Tree
When the debugger is started, you can click the View | Project Window to display the Project Files Tree (the Project window) and the structure of the project files can be examined by exploring the project tree.
In this view, it is possible to double-click files (the project consists of) and double-click individual predicates. The result will be that a source code editor opens up with the caret pointing to the clicked item.
Source Code Windows
When the IDE starts debugging a project, it automatically runs the target executable under the debugger, and breaks the program execution at the goal section entry point. The debugger opens the correspondent (containing the goal section) Visual Prolog source file in the IDE text editor.
Notice the blue arrow pointing to the executing predicate:
mainExe::run(main::run).
This arrow is the Instruction Pointer, which always points to the currently executing predicate in source code windows. That is, you can follow the Instruction Pointer moving to trace execution of the program.
The debugger changes the color of the Instruction Pointer arrow when it executes a predicate, which fails or which raises an exception.
If you have moved in the program source windows and have lost the Instruction Pointer, then you can easy find it with the menu command Debug | Go to Executing Predicate Source (Ctrl+E). It sets the cursor to the line containing the currently executing predicate (to the line pointed by the Instruction Pointer).
Run Stack Window
The Run Stack consists of three kinds of items:
- Continue item – marked with . It describes ordinary executable clauses, which do not produce backtrack points and are not trapped.
- BackTrack item – marked with .It describes a clause of a nondeterministic predicate. The next clause of this predicate can be executed when a program failure of this clause occurs. Such items occur when a clause of a predicate, which creates a backtrack point (can produce more than one solution) is called.
- TrapTrack item – marked with or . They describe a continue item (clause), which will be resumed in any case independently whether an error condition occurs or no. For example, such item is created when a predicate call is trapped with the trap/3 predicate. The icon is used to mark trapped clauses of deterministic predicates. The icon is used to mark trapped clauses of nondeterministic predicates.
The BackTrack (marked with ) and TrapTrack items (marked with ) are backtracking points. The clause, marked by one of these items, will be resumed and the program execution will be continued after the corresponding failure or an error occurs.
The typical example of the Run Stack window is presented in the following picture:
Pop-up Menu
The Run Stack window has the pop-up context menu:
For each selected item in the tree, this menu contains items:
- Refresh
- It refreshes all the Run Stack window contents, rebuilds the tree.
It also refreshes the Variables window (if it is displayed).
- Go To Code
- Activates the Prolog source editor and places the cursor at the Prolog clause corresponding to the item selected in the Run Stack window. If the item does not correspond to a Prolog module with debug information, then the Disassembly window will be opened and the cursor will be placed onto the corresponding assembler instruction. The same action is caused by double-click a predicate call in the Run Stack window.
- Copy Line
- It copies the selected line contents to the clipboard.
- Show Domains
- This option turns ON/OFF displaying domains of variables.
- Show Values
- This option turns ON/OFF displaying values of variables.
The Run Stack window can be activated by the IDE menu View | Run Stack.
Variables Window
The Variables window can be activated either by Ctrl+Alt+V or from the IDE menu View | Variables for Current Clause.
Variables Window Contents
The Variables window displays the tree of all program variables and facts from the traced clause, which are already created by the program at the current tracing step. These are: all variables and all object facts (fact variables), which are created in the clause before the executing instruction, and all class facts (fact variables), which can be used in this clause (declared in this class implementation).
The top line of the window displays the declaration of the predicate, whose clause is executed.
The Variables window content is updated after every trace step.
Pop-up Context Menu
The Variables in the Current Clause window has the following pop-up context menu:
This menu contains items:
- Insert into Watch Window
- Opens the Watch Window and moves there selected variable.
- Copy
- This command copies the contents of the line selected in the Variables window to the clipboard.
- Show as Hexadecimal
- Shows integral values in the hexadecimal format.
- Show as Decimal
- Shows integral values in the decimal format.
- Show as Octal
- Shows integral values in the octal format.
- Show Domains
- This option turns ON/OFF displaying the domains after variable names.
- Show Variable Addresses
- This option turns ON/OFF displaying the addresses after variable names.
- Find
- This command allows search variable by name.
- Copy Tree
- This command copies the contents of the window to the clipboard.
Facts Window
Class Facts
The Facts window always shows the current contents of all class fact databases defined in the program being debugged.
Simple example:
Pressing CTRL+ALT+F opens Facts window:
Clicking icons opens sub-trees:
Facts window automatically goes to the fact that is selected in the text editor (if any):
Objects Facts you cat look like a components of object variables in the Variables window
Pop-up Context Menu
The Facts Window has the following pop-up context menu:
This menu contains items:
- Insert into Watch Window
- Opens the Watch Window and moves there selected fact.
- Copy
- This command copies the contents of the line selected in the Facts window to the clipboard.
- Show as Hexadecimal
- Shows integral values in the hexadecimal format.
- Show as Decimal
- Shows integral values in the decimal format.
- Show as Octal
- Shows integral values in the octal format.
- Show Domains
- This option turns ON/OFF displaying the domains after facts names.
- Show Addresses
- This option turns ON/OFF displaying the addresses after facts names.
- Find
- This command allows search fact by name.
- Copy Tree
- This command copies the contents of the window to the clipboard.
Breakpoints Window
Introduction
The Breakpoints window shows all breakpoints, which have been set in the program being debugged.
You can set a breakpoint onto any executable line in program source files (or in the Disassembly window, where a breakpoint can be set on any instruction of the program being debugged).
There are two kinds of breakpoints: hard and soft. Hard breakpoints are active in any debugging mode. Soft breakpoints are active in normal debugging mode but disabled in a special mode of quick debugging, called Fast Forward Mode.
Breakpoints Window Contents
The Breakpoints window for each breakpoint includes Status, Source, Line, Count, Comment and Action, where:
- Status
- Shows whether the breakpoint is hard or soft.
- Hard
- Soft
- Invalid
- Source
- This column shows the source string:
SourceName
- where:
- SourceName
- The description of a predicate in the address space of whose clauses the breakpoint is set:
- If the breakpoint is set in Prolog sources, then SourceName is the filename in which the breakpoint is set. It is displayed with the format:
FileName '(' Path ')'
- The Path can use [..\Make_Facility\Make_Facility.htm#Build_Symbols Build script symbols].
- If the breakpoint is set in the Disassembly window, then SourceName has the format:
--- assembler: AddressValue
- AddressValue is the hexadecimal address of the breakpoint in the assembler code of the predicate in which the breakpoint is set.
- Line
- When the breakpoint is set in a Prolog source file, then this column displays the number of the line the breakpoint is set on.
When the breakpoint is set in the Disassembly window, then the number of the line is equal to 0.
- When the breakpoint is set in a Prolog source file, then this column displays the number of the line the breakpoint is set on.
- Count
- This column displays counts of breakpoints.
- Comment
- This column displays comment strings of breakpoints.
- Action
- This column displays the script text of a breakpoint. The script is performed each time the program reaches the breakpoint.
Breakpoints in Prolog and Disassembly Windows
Breakpoints can be set in Prolog source files and in the Disassembly window:
- In Prolog sources valid breakpoints can be set only on lines containing executable instructions. That is, breakpoints can be set only in predicate clauses on lines containing predicate calls, otherwise the breakpoints that are set on non-clause lines would be marked as invalid. The breakpoints that are set on clause lines that do not contain predicate calls would be shifted to the lines containing such calls (if any), but the initial line would be marked with . Valid breakpoints are marked with red circles or in Prolog sources and are shown in the Disassembly window as blue circles or . If a Prolog clause has several assembler implementations (when the clause has several flow patterns), then each breakpoint in Prolog sources can generate several breakpoints in the Disassembly window.
- Breakpoints that are set in the Disassembly window are marked with red circles or . Such breakpoint can be later overwritten by a breakpoint (marked with blue circles or ) that is set in Prolog sources on the same address as the breakpoint set in the Disassembly window.
Notice that after modification and recompilation of the project some breakpoints that are set in the Disassembly window can be cleared (if other instructions are placed at breakpoint addresses.)
All breakpoints which are set in a program are seen in the Breakpoints window.
Breakpoint Properties
Each breakpoint has properties, which can be modified in the Breakpoint Properties dialog:
In this dialog:
The top line contains:
- If the breakpoint is set in Prolog sources, then the top line has format:
File: FileName Line: LineNumber
- FileName is the name of the Prolog source file in which the breakpoint is set.
- LineNumber is the number of the line on which the breakpoint is set.
- If the breakpoint is set in the Disassembly window, then the top line has format:
Breakpoint Address:Address
- Address is the breakpoint address in the program memory as it is seen in the Disassembly window.
Count Value
- Shows the current number of activations of the breakpoint since its creation. The user cannot modify this value. This value increases by 1 each time when the program reaches the breakpoint.
Hard
- This check box controls the Hard/Soft state of the breakpoint. When you turn a breakpoint to Hard, then it will be activated in any debugging mode. When you turn a breakpoint to Soft, then it will be activated only in normal (not Fast Forward) debugging mode.
Comment Comment string
- In this edit box you can type in a Comment string. By default it has the value of the corresponding line in the source file.
Action Script text
- In this box you can type in a Script text.
Note. If a module has been built without debug information (this can be done by changing /debug:full to /nodebug in the command line compiler options in the [..\Project_Settings\Application_Expert.htm#Build_Options build script rules] for pro->obj: and pack->obj:) then you will not be able to set a breakpoint in the Prolog sources of the module.
Notice that it does not matter in which window you remove a breakpoint (in Prolog sources, in the Breakpoints window or in the Disassembly window). In any case, removing a breakpoint deletes the breakpoint from the program.
Pop-up Menu
The Breakpoints window has the pop-up context menu:
To activate this menu, select a breakpoint and press the right mouse button. This menu contains items:
- Go to Source
- If the breakpoint is set in the Prolog sources, then the Go to Code activates the Prolog source code editor, and moves the cursor to the Prolog code corresponding to the specified breakpoint. If the breakpoint is set in the Disassembly window, then the Go to Code moves the view to this breakpoint in the Disassembly window. The same action is performed by double-click the breakpoint or by pressing the Enter on the breakpoint.
- Properties
- Invokes the Breakpoint Properties dialog for the selected breakpoint.
- Toggle (Turn to Hard/Soft)
- Switches the Hard/Soft state of the selected breakpoints.
- Delete
- Deletes the selected breakpoints.
- Turn to Hard All
- Sets the state of all breakpoints that are set in the program to Hard.
- Turn to Soft All
- Sets the state of all breakpoints that are set in the program to Soft.
- Remove All
- Removes all breakpoints that are set in the program.
The Breakpoints window is auto-updated for any breakpoint updating.
The Breakpoints window can be activated either by Ctrl+Alt+B or from the IDE menu View | Breakpoints.
Threads Window
The Threads window shows information about the process being debugged and its threads.
The Threads window looks like following:
Names displayed in the header of the window columns are the following:
- TID
- This column displays thread identifiers of all threads created by the process being debugged.
- Current
- This column identifies the current thread by the * sign. In the Variables window you can see only variables of predicates executed in the current thread.
- State
- Displays states of threads. States can be Running, Stopped, and Suspend.
Running The thread has been started, it is not suspended (see thread::suspend/0->, syncObject::wait/0->, syncObject::wait/1->) or terminated (see thread::terminate/1).
Suspend The thread is in suspended state (see thread::createSuspended/3, thread::suspend/0->, syncObject::wait/0->, syncObject::wait/1->).
Stopped The thread was created and then stopped on a breakpoint, but it is not suspended (see thread::suspend/0->, syncObject::wait/0->, syncObject::wait/1->). If you set suspended state to a Stopped thread, then it turns into the Suspend state.
- Time
- Thread creation time.
- User time
- Processor time in the user-mode used by the thread.
- Kernel Time
- Processor time in the kernel-mode used by the thread.
- Priority
- The priority level of the thread. Here can be displayed the following numbers 2, 1, 0, -1, -2.
- Predicate
- This field contains the name of the currently executed thread's predicate (if it is possible to determine it).
Displayed Number | Priority Name | Description |
---|---|---|
2 | Highest | The thread can be scheduled before threads with any other priority. |
1 | AboveNormal | The thread can be scheduled after threads with Highest priority and before those with Normal priority. |
0 | Normal | The thread can be scheduled after threads with AboveNormal priority and before those with BelowNormal priority. Threads have Normal priority by default. |
-1 | BelowNormal | The thread can be scheduled after threads with Normal priority and before those with Lowest priority. |
-2 | Lowest | The thread can be scheduled after threads with any other priority. |
Pop-up Menu
The Threads window has the pop-up context menu. The same commands can be activated from the Thread sub-menu of the IDE task menu.
- Goto Source
- Opens the text editor and places the cursor onto the predicate, which created the selected thread.
- Set Current
- Sets the selected thread as current.
- Resume
- Resumes the run of the selected thread.
- Suspend
- Suspends the selected thread.
- Copy
- Copies the contents of the line selected in the Threads window to the clipboard.
- Copy All
- Copies the contents of the Threads window to the clipboard.
The Threads window is updated after changing any displayed parameter.
The Threads window can be activated either by CTRL+Alt+H or from the IDE menu View | Threads.
Disassembly Window
Disassembly Window Contents
The Disassembly window shows the assembly language interpretation of the inspected code.
The disassembly starts from the specified top address toward the upper memory and prints each instruction on a new line.
Each line is printed by the pattern:
LineMarkers Address [ HexCode ] AssemblerCommand
where:
LineMarkers
- Are the instruction pointer and the breakpoint (or ) markers, which can mark this line.
Address
- The start address of the instruction code.
HexCode
- This is the hexadecimal instruction code. This field can be shown/hidden from the pop-up menu of the Disassembly window by checking the Show OpCodes item.
AssemblerCommand
- This is the assembler command corresponding to the instruction code. Assembler commands have the Intel standard assembler abbreviation. If a certain address is resolved to an external name, then this name will be printed in the command column.
The instruction, which will be executed at the next trace step, is marked with the File:De db InstructionPointer.png Instruction pointer in the LineMarkers field.
Example:
Pop-up Menu
The Disassembly window has the pop-up context menu with the followin commands:
- Go To Address
- Invokes the Go to Address dialog
- File:Db DisAsm Go2Address.png
- to type in the address of the instruction, which should be displayed in the top line of the Disassembly window. The Address should be specified in the hexadecimal format. This dialog allows typing symbolic external link names and symbolic CPU register names.
- Go To EIP
- Updates the Disassembly window and places the cursor at the address of the instruction on which the program execution is suspended.
- Breakpoint…
- Allows handling the breakpoint File:De db BreakPoints en.png (or File:De db BreakPoints dis.png) for the assembler instruction pointed by the cursor. It has the following sub-commands:
- File:Db DisAsm PopUp.png
- Toggle Breakpoint
- Sets or removes a breakpoint at the instruction with the address pointed by the cursor.
- Enable / Disable
- Enables / Disables the breakpoint pointed by the cursor. This item is disabled if there is no breakpoint at the address pointed by the cursor.
- Properties
- Invokes the Breakpoint Properties dialog for the breakpoint pointed by the cursor. This item is disabled if there is no breakpoint at the address pointed by the cursor.
- Toggle Breakpoint
- Go To Source
- Activates the IDE source code editor and sets the cursor at the predicate whose assembler instruction is pointed by the cursor in the Disassembly window. (When it is possible.)
- Copy
- Copies lines selected in the Disassembly window to the clipboard. A selection can be performed with the Shift+Up Arrow and Shift+Down Arrow key combinations.
- Show OpCodes
- Checking and unchecking this item hides/shows hex images of operation (instruction) codes (OpCodes). These hex instruction codes are shown in the HexCode field.
- Source Annotation
- Checking OFF/ON this item hides/shows object names, corresponding to predicate entry points. Each object name is printed on a new line before the corresponding instruction line.
- Show Hints
- Shows additional information about the instruction being executed.
The Disassembly window is updated after each trace step of the debugger.
Disassembly Window Commands
- Trace Into (F11) command
- Tracing in the Disassembly window with the Step Into (F7) command performs execution of one assembler instruction (including entering into procedures if any). That is, if the Step Over command will execute a call instruction as one trace step, then the Step Into command will go into the called procedure. It usually executes disassembler instructions line after line.
- Step Over (F10) command
- Tracing in the Disassembly window with the Step Over (F10) command performs execution of one assembler instruction (including execution of call instructions). So the Step Over (F10) command works almost the same way as the Trace Into (F11) command except for execution of call instructions. In difference to the Trace Into (F11) command, it tries to perform call instructions as one step and reaches the next line only if the called code returns to that line.
- Run to Cursor (CTRL+F10) command
- Tracing in the Disassembly window with the Run to Cursor (CTRL+F10) command works in the following way. The debugger places an invisible breakpoint at the address corresponding to the instruction specified by the cursor and performs the Debug Run (F5) command. It depends only upon the program code whether the program will reach this instruction or will never reach it.
The Disassembly window can be activated:
- by Shift+Alt+1
- by Ctrl+D from the traceable source code. The topmost line of the Disassembly window displays the address of the disassembler instruction corresponding to the predicate pointed by the cursor in the source code.
- from the IDE menu View | Disassembly
If the tracing code has no debug information, then the Disassembly window is opened initially (when the debugger starts) and the instruction pointer points to the executing assembler instruction.