To support multiple high-level programming languages (HLL), Debug Tool adapts its commands to the HLLs, provides interpretive subsets of commands from the various HLLs, and maps common attributes of data types across the languages. It evaluates HLL expressions and handles constants and variables.
The topics below describe how Debug Tool makes it possible for you to debug programs consisting of different languages, structures, conventions, variables, and methods of evaluating expressions.
A general rule to remember is that Debug Tool tries to let the language itself guide how Debug Tool works with it.
Refer to the following topics for more information related to the material discussed in this topic.
When you enter an expression, Debug Tool records the programming language in effect at that time. When the expression is run, Debug Tool passes it to the language run time in effect when you entered the expression. This run time might be different from the one in effect when the expression is run.
When you enter an expression that will not be run immediately, you should fully qualify all program variables. Qualifying the variables assures that proper context information (such as load module and block) is passed to the language run time when the expression is run. Otherwise, the context might not be the one you intended when you set the breakpoint, and the language run time might not evaluate the expression.
Refer to the following topics for more information related to the material discussed in this topic.
Debug Tool supports the use of HLL variables and constants, both as a part of evaluating portions of your test program and in declaring and using session variables.
Three general types of variables supported by Debug Tool are:
Some variable references require language-specific evaluation, such as pointer referencing or subscript evaluation. Once again, the Debug Tool interprets each case in the manner of the HLL in question. Below is a list of some of the areas where Debug Tool accepts a different form of reference depending on the current programming language:
You can use both string constants and numeric constants. Debug Tool accepts both types of constants in C and C++, COBOL, and PL/I.
To allow you to use familiar commands while in a debug session, Debug Tool provides an interpretive subset of commands for each language. This consists of commands that have the same syntax, whether used with Debug Tool or when writing application programs. You use these commands in Debug Tool as though you were coding in the original language.
Use the SET PROGRAMMING LANGUAGE command to set the current programming language to the desired language. The current programming language determines how commands are parsed. If you SET PROGRAMMING LANGUAGE to AUTOMATIC, every time the current qualification changes to a module in a different language, the current programming language is automatically updated.
The following types of Debug Tool commands have the same syntax (or a subset of it) as the corresponding statements (if defined) in each supported programming language:
In addition, Debug Tool supports special kinds of commands for some languages.
Each HLL defines a concept of name scoping to allow you, within a single compile unit, to know what data is referenced when a name is used (for example, if you use the same variable name in two different procedures). Similarly, Debug Tool defines the concepts of qualifiers and point of view for the run-time environment to allow you to reference all variables in a program, no matter how many subroutines it contains. The assignment x = 5 does not appear difficult for Debug Tool to process. However, if you declare x in more than one subroutine, the situation is no longer obvious. If x is not in the currently executing compile unit, you need a way to tell Debug Tool how to determine the proper x.
You also need a way to change the Debug Tool’s point of view to allow it to reference variables it cannot currently see (that is, variables that are not within the scope of the currently executing block or compile unit, depending upon the HLL’s concept of name scoping).
Refer to the following topics for more information related to the material discussed in this topic.
Qualification is a method you can use to specify to what procedure or load module a particular variable belongs. You do this by prefacing the variable with the block, compile unit, and load module (or as many of these labels as are necessary), separating each label with a colon (or double colon following the load module specification) and a greater-than sign (:>), as follows:
load_name::>cu_name:>block_name:>object
This procedure, known as explicit qualification, lets Debug Tool know precisely where the variable is.
If required, load_name is the load module name. It is required only when the program consists of multiple load modules and when you want to change the qualification to other than the current load module. load_name can be the Debug Tool variable %LOAD.
If required, cu_name is the compile unit name. The cu_name is required only when you want to change the qualification to other than the currently qualified compile unit. cu_name can be the Debug Tool variable %CU.
If required, block_name is the program block name. The block_name is required only when you want to change the qualification to other than the currently qualified block. block_name can be the Debug Tool variable %BLOCK.
For PL/I only:
LM::>PROC1:>variableis valid.
LM::>PROC1:>PROC1:>variableis not valid.
For C++ only:
qualify block %load::>"USERID.SOURCE.LISTING(ICCD226)":>ICCD2263()
AT ENTRY "USERID.SOURCE.LISTING(ICCD0320)":>ICCD0320(long,long)
Use the Debug Tool command DESCRIBE CUS to give you the correct BLOCK or CU qualification needed.
Use the LIST NAMES command to show all polymorphic functions of a given name. For the example above, LIST NAMES "ICCD0320*" would list all polymorphic functions called ICCD0320.
You do not have to preface variables in the currently executing compile unit. These are already known to Debug Tool; in other words, they are implicitly qualified.
In order for attempts at qualifying a variable to work, each block must have a name. Blocks that have not received a name are named by Debug Tool, using the form: %BLOCKnnn, where nnn is a number that relates to the position of the block in the program. To find out the Debug Tool’s name for the current block, use the DESCRIBE PROGRAMS command.
Refer to the following topics for more information related to the material discussed in this topic.
The point of view is usually the currently executing block. You can get to inaccessible data by changing the point of view using the SET QUALIFY command with the following operand.
load_name::>cu_name:>block_name
Each time you update any of the three Debug Tool variables %CU, %PROGRAM, or %BLOCK, all four variables (%CU, %PROGRAM, %LOAD, and %BLOCK) are automatically updated to reflect the new point of view. If you change %LOAD using SET QUALIFY LOAD, only %LOAD is updated to the new point of view. The other three Debug Tool variables remain unchanged. For example, suppose your program is currently suspended at loadx::>cux:>blockx. Also, the load module loadz, containing the compile unit cuz and the block blockz, is known to Debug Tool. The settings currently in effect are:
If you enter any of the following commands:
SET QUALIFY BLOCK blockz; SET QUALIFY BLOCK cuz:>blockz; SET QUALIFY BLOCK loadz::>cuz:>blockz;
the following settings are in effect:
If you are debugging a program that has multiple enclaves, SET QUALIFY can be used to identify references and statement numbers in any enclave by resetting the point of view to a new block, compile unit, or load module.
To suspend program execution just before your application would terminate abnormally, start your application with the following runtime options:
TRAP(ON) TEST(ALL,*,NOPROMPT,*)
When a condition is signaled in your application, Debug Tool prompts you and you can then dynamically code around the problem. For example, you can initialize a pointer, allocate memory, or change the course of the program with the GOTO command. You can also indicate to Language Environment’s condition handler, that you have handled the condition by issuing a GO BYPASS command. Be aware that some of the code that follows the instruction that raised the condition might rely on data that was not properly stored or handled.
When debugging with Debug Tool, you can (depending on your host system) either instruct the debugger to handle program exceptions and conditions, or pass them on to your own exception handler. Programs also have access to Language Environment services to deal with program exceptions and conditions.
Refer to the following topics for more information related to the material discussed in this topic.
You can use either or both of the two methods during a debugging session to ensure that Debug Tool gains control at the occurrence of HLL conditions.
If you specify TEST(ALL) as a run-time option when you begin your debug session, Debug Tool gains control at the occurrence of most conditions.
You can also direct Debug Tool to respond to the occurrence of conditions by using the AT OCCURRENCE command to define breakpoints. These breakpoints halt processing of your program when a condition is raised, after which Debug Tool is given control. It then processes the commands you specified when you defined the breakpoints.
There are several ways a condition can occur, and several ways it can be handled.
A condition can occur during your Debug Tool session when:
When an HLL condition occurs and you have defined a breakpoint with associated actions, those actions are first performed. What happens next depends on how the actions end.
If, after the execution of any defined breakpoint, control returns to your program with a GO, the condition is raised again in the program (if possible and still applicable). If you use a GOTO to bypass the failing statement, you also bypass your program’s error handling facilities.
Refer to the following topics for more information related to the material discussed in this topic.
When an exception such as division by zero is detected in a Debug Tool expression, you can use the Debug Tool command SET WARNING to control Debug Tool and program response. During an interactive Debug Tool session, such exceptions are sometimes due to typing errors and so are probably not intended to be passed to the program. If you do not want errors in Debug Tool expressions to be passed to your program, use SET WARNING ON. Expressions containing such errors are terminated, and a warning message is displayed.
However, you might want to pass an exception to your program, perhaps to test an error recovery procedure. In this case, use SET WARNING OFF.
Refer to the following topics for more information related to the material discussed in this topic.
Language Environment simplifies the debugging of multilanguage applications by providing a single run-time environment and interlanguage communication (ILC).
When the need to debug a multilanguage application arises, you can find yourself facing one of the following scenarios:
When writing a multilanguage application, a number of special considerations arise because you must work outside the scope of any single language. The Language Environment initialization process establishes an environment tailored to the set of HLLs constituting the main load module of your application program. This removes the need to make explicit calls to manipulate the environment. Also, termination of the Language Environment environment is accomplished in an orderly fashion, regardless of the mixture of HLLs present in the application.
Refer to the following topics for more information related to the material discussed in this topic.
If you are debugging a program written in a combination of languages supported by Language Environment and compiled by supported compilers, very little is required in the way of special actions. Debug Tool normally recognizes a change in programming languages and automatically switches to the correct language when a breakpoint is reached. If desired, you can use the SET PROGRAMMING LANGUAGE command to stay in the language you specify; however, you can only access variables defined in the currently set programming language.
When defining session variables you want to access from compile units of different languages, you must define them with compatible attributes.
Refer to the following topics for more information related to the material discussed in this topic.
While working in one language, you can declare session variables that you can continue to use after calling in a load module of a different language. The table below shows how the attributes of session variables are mapped across programming languages. Session variables with attributes not shown in the table cannot be accessed from other programming languages. (Some attributes supported for C and C++ or PL/I session variables cannot be mapped to other languages; session variables defined with these attributes cannot be accessed outside the defining language. However, all of the supported attributes for COBOL session variables can be mapped to equivalent supported attributes in C and C++ and PL/I, so any session variable that you declare with COBOL can be accessed from C and C++ and PL/I.)
| Machine attributes | PL/I attributes | C and C++ attributes | COBOL attributes | Assembler and disassembly attributes |
|---|---|---|---|---|
|
byte |
CHAR(1) |
unsigned char |
PICTURE X |
DS X or DS C |
|
byte string |
CHAR(j) |
unsigned char[j] |
PICTURE X(j) |
DS XLj or DS CLj |
|
halfword |
FIXED BIN(15,0) |
signed short int |
PICTURE S9(j<=4) USAGE BINARY |
DS H |
|
fullword |
FIXED BIN(31,0) |
signed long int |
PICTURE S9(4<j<=9) USAGE BINARY |
DS F |
|
floating point |
FLOAT BIN(21) or FLOAT DEC(6) |
float |
USAGE COMP-1 |
DS E |
|
long floating point |
FLOAT BIN(53) or FLOAT DEC(16) |
double |
USAGE COMP-2 |
DS D |
|
extended floating point |
FLOAT BIN(109) or FLOAT DEC(33) |
long double |
n/a |
DS L |
|
fullword pointer |
POINTER |
* |
USAGE POINTER |
DS A |
When declaring session variables, remember that C and C++ variable names are case-sensitive. When the current programming language is C and C++, only session variables that are declared with uppercase names can be shared with COBOL or PL/I. When the current programming language is COBOL or PL/I, session variable names in mixed or lowercase are mapped to uppercase. These COBOL or PL/I session variables can be declared or referenced using any mixture of lowercase and uppercase characters and it makes no difference. However, if the session variable is shared with C and C++, within C and C++, it can only be referred to with all uppercase characters (since a variable name composed of the same characters, but with one or more characters in lowercase, is a different variable name in C and C++).
Session variables with incompatible attributes cannot be shared between other programming languages, but they do cause session variables with the same names to be deleted. For example, COBOL has no equivalent to PL/I’s FLOAT DEC(33) or C’s long double. With the current programming language COBOL, if a session variable X is declared PICTURE S9(4), it will exist when the current programming language setting is PL/I with the attributes FIXED BIN(15,0) and when the current programming language setting is C with the attributes signed short int. If the current programming language setting is changed to PL/I and a session variable X is declared FLOAT DEC(33), the X declared by COBOL will no longer exist. The variable X declared by PL/I will exist when the current programming language setting is C with the attributes long double.
Refer to the following topics for more information related to the material discussed in this topic.
If you want to create a commands file to use across different programming languages, Creating a commands file describes some guidelines you should follow to ensure that the commands files works correctly.
Coexistence with other debuggers cannot be guaranteed because there can be situations where multiple debuggers might contend for use of storage, facilities, and interfaces that are intended for only one requester.
Refer to the following topics for more information related to the material discussed in this topic.
Compile units or program units written in unsupported high- or low-level languages, or in older releases of HLLs, are tolerated. See Using CODE/370 with VS COBOL II and OS PL/I for information about two unsupported HLLs that can be used with Debug Tool.
Refer to the following topics for more information related to the material discussed in this topic.