Tru64 UNIX
Ladebug Debugger Manual


Previous Contents Index

7.8 Debugging Ada Elaboration Code

In Ada, as in other languages, the initial entry point is the procedure main, but unlike other languages, main in Ada is not the top-level application procedure. Instead, the elaboration code, which contains initialization routines for Ada-specific constructs such as packages, is called from a fabricated main routine before the top-level application is called.

If you wish to debug elaboration code, you can set a breakpoint on main, step to elaboration code initialization routine calls, and step into these routines. To ignore elaboration code, you can set a breakpoint in the Ada subprogram.

7.9 Accessing Unconstrained Array Types

Accesses to unconstrained arrays are implemented as pointers to structures known as descriptors or dope vectors. For example:


procedure Dbg_30 is 
   type A1 is access String; 
   X1 : A1 := new String'("123"); 
begin 
   null; 
end; 

When you enter the print command, the debugger displays the pointer address (the address of the first (lo1) component) and the values of the first and last components. For example:


 
(ladebug) p *X1 
struct { 
    pointer = 0x14000c620; 
    lo1 = 1; 
    hi1 = 3; 
} 

To examine individual components, use the dereferencing operator (->) as follows:


(ladebug) p X1->pointer[0]; p X1->pointer[2] 
struct { 
   value = '1'; 
} 
struct { 
   value = '3'; 
} 

7.10 Accessing Incomplete Types Completed in Another Compilation Unit

The full type often appears in a different compilation unit than the access type, which makes values of these types difficult to examine. Except in cases where the full type is an array type, you can examine values by carefully setting scopes and explicit type conversion. For example:


package Tmp_Pkg is 
   type A_T is private; 
   X : A_T; 
private 
   type T; 
   type A_T is access T; 
end Tmp_Pkg; 
 
package body Tmp_Pkg is 
   type T is record C1, C2 : Integer; end record; 
begin 
   X := new T'(71,72); 
end Tmp_Pkg; 
 
with Tmp_Pkg; 
procedure Tmp is 
begin 
   null; 
   -- 
   -- (ladebug) whereis X 
   -- "tmp_pkg_.ada"`X 
   -- 
   -- (ladebug) p "/c/project/aosf_ft2/tmp_pkg_.ada"`X 
   -- 0x14000c600 
   -- 
   -- (ladebug) file tmp_pkg.ada 
   -- 
   -- (ladebug) p * ( (T*) (0x14000c600) ) 
   -- struct { 
   --         C1 = 71; 
   --         C2 = 72; 
   --     } 
   -- 
end; 

7.11 Limitations on Ladebug Support for DEC Ada

Ladebug and the Tru64 UNIX operating system support the DEC Ada language with certain limitations, which are described in the following sections.

7.11.1 Limitations for Expressions in Ladebug Commands

Expressions in Ladebug commands use C source language syntax for operators and expressions. Data is printed as the equivalent C data type.

Table 7-1 shows Ada expressions and the debugger equivalents.

Table 7-1 Ada Expressions and Debugger Equivalents
Ada Expression Debugger Equivalent
Name See Section 7.4.
Binary operations and unary operations Only integer, floating, and Boolean expressions are easily expressed.
a+b,-,* a+b,-,*
a/b a/b
a = b /= < <= > >= a :=,= b != < <= > >=
a and b a&&b
a or b a||b
a rem b a%b
not (a=b) !(a:=,=b)
--a --a
Qualified expressions None. There is no easy way of evaluating subtype bounds.
Type conversions Only simple numeric conversions are supported, and the bounds checking cannot be done. Furthermore, float -> integer truncates rather than rounds.

integer -> float
(ladebug) print (float) (2147483647)

2147483648.0
(ladebug) print (double) (2147483647)
2147483647.0
Attributes None, but if E is an enumeration type with default representations for the values then
E'PRED(X) is the same as x-1.
E'SUCC(X) is the same as x+1
p.all *p (pointer reference)
p.m p -> m (member of an "access record" type)

7.11.2 Limitations in Data Types

This section lists the limitation notes by data type. For more information on these types, with examples, see the Developing Ada Programs on Tru64 UNIX Systems manual. Also see the the DEC Ada release notes for detailed information on debugging.

All Types

The debugger, unlike the Ada language, allows out-of-bounds assignments to be performed.

Integer Types

If integer types of different sizes are mixed (for example, byte-integer and word-integer), the one with the smaller size is converted to the larger size.

Floating-Point Types

If integer and floating-point types are mixed in an expression, the debugger converts the integer type to a floating-point type.

The debugger displays floating-point values that are exact integers in integer literal format.

Fixed-Point Types

The debugger displays fixed-point values as real-type literals or as structures. The structure contains values for the sign and the mantissa. To display the structure's value, multiply the sign and mantissa values. For example:


procedure Tmp3 is 
    type F is delta 0.1 range -3.0 .. 9.0; 
    X : F := 1.0; 
begin 
    X := X+1.0; 
end; 
 
(ladebug) s 
stopped at [Tmp3:5 0x1200023dc] 
    5       X := X+1.0; 
 
(ladebug) print X 
struct { 
    fixed_point, small = 0.625E-1 * mantissa = 32; 
} 

Enumeration Types

The debugger displays enumeration values as the actual enumeral or its position.

Enumeration values must be manually converted to 'pos values before you can use them as array indices.

Array Types

The debugger displays string array values in horizontal ASCII format, enclosed in quotation ("x") marks. A single component (character) is displayed within single quotation ('x') marks.

The debugger allows you to assign a component value to a single component; you cannot assign using an entire array or array aggregate.

Arrays whose components are neither a single bit nor a multiple of bytes are described to the debugger as structures; a print command displays only the first component of such arrays.

Records

The debugger cannot display record components whose offsets from the start of the record are not known at compile time.

For variant records, however, the debugger can display the entire record object that has been declared with the default variant value. The debugger allows you to print or assign a value to a component of a record variant that is not active.

Access Types

The debugger does not support allocators, so you cannot create new access objects with the debugger. When you specify the name of an access object, the debugger displays the memory location of the object it designates. You can examine the memory location value.

7.11.3 Limitations for Tasking Programs

When you debug Ada tasking programs, you use the debugger and the DEC Ada ada_debug routine.

7.12 Debugging Programs That Generate an Exception

Ada exceptions can be raised in the following cases:

When an exception occurs, you need to determine the following:

  1. Where the exception is being raised
  2. How the exception is being raised (by the raise statement or by language check)
  3. Why the exception occurred, by either:

The following sections give more detail.

Determining Where the Exception Is Being Raised

There are two ways to determine where an exception is being raised:

Determining How the Exception Is Being Raised

Having determined where the exception is occurring, examine your program code to see whether an explicit raise statement has caused the exception. If a raise statement does not appear, then the exception is the result of an Ada language check.

Determining Why the Exception Is Being Raised

If the exception is raised by an explicit raise statement, examine your code to determine why the raise statement was executed.

If the exception is raised by a language check, see Developing Ada Programs on Tru64 UNIX Systems for tips on pinpointing the error.

7.13 Debugging Optimized Programs

The DEC Ada compiler performs code optimizations by default, unless you specify the -g flag. Debugging optimized code is recommended only if unoptimized code is unavailable. It is extremely difficult to understand your program by examining the workings of its optimized form.

If you must debug optimized code, then note the following changes that optimization may make in your source code:

You may wish to make use of the following aids when debugging optimized code:


Chapter 8
Debugging DEC COBOL Programs

8.1 Significant Supported Features

To help you debug DEC COBOL programs on the Tru64 UNIX operating system, Ladebug supports:

The following features are also supported for DEC COBOL debugging:

Some of the features are further described in this chapter. This chapter also:

8.2 DEC COBOL Flags for Debugging

To use the Ladebug debugger on a COBOL program, invoke the COBOL compiler with the appropriate debugging flag: -g, -g2, or -g3. For example:


% cobol -g -o sample sample.cob

The -g flag on the compiler command instructs the compiler to write the program's debugger symbol table into the executable image. This flag also turns off optimization; optimization (which is the default for nondebugger compilations) could cause a confusing debugging session.

For DIGITAL UNIX Vesion 3.2 systems, Table 8-1 summarizes the information provided by the -gn flags and their relationship to the -On flags, which control optimization. Refer to your language compiler documentation for information about compiler flag defaults for DIGITAL UNIX Version 5.0.

Table 8-1 Summary of Symbol Table Flags
Flag Traceback
Information
Debugging Symbol
Table Information
Effect on -On Flags
-g0 No No Default is -O4 (full optimization).
-g1 (default) Yes No Default is -O4 (full optimization).
-g2 or -g Yes Yes. For unoptimized code only. Changes default to -O0 (no optimization).
-g3 Yes Yes. Use with optimized code. Inaccuracies may result. Default is -O4 (full optimization).

If you specify -g, -g2, or -g3, the compiler provides symbol table information for symbolic debugging. The symbol table allows the debugger to translate virtual addresses into source program routine names and compiler-generated line numbers.

Later, to remove this symbol table information, you can compile and link it again (without the -g flag) to create a new executable program or use the strip command (see strip(1)) on the existing executable program.

The -g2 or -g flag provides symbol table information for symbolic debugging unoptimized code. If you use the -g2 or -g flag and do not specify an -On flag, the default optimization level changes to -O0 (in all other cases, the default optimization level is -O4) . If you use this flag and specify an -On flag other than -O0, a warning message is displayed. For example:


% cobol -g -O sample sample.cob
cobol: Warning: file not optimized; use -g3 for debug with optimize 
%

The -g3 flag is for symbolic debugging with optimized code.

Typical uses of the debugging flags at the various stages of program development are as follows:

8.3 Support for COBOL Identifiers

Ladebug supports the case insensitivity of COBOL identifiers and the hyphen-underscore exchanges made by the DEC COBOL compiler.

In case-insensitive languages (such as COBOL, Fortran, and Ada), you can enter identifiers in either uppercase or lowercase, or a combination of both. For example, the following are all legal and equivalent identifiers:


Identifier IDENTIFIER identifier IdEnTiFiEr 

Ladebug and the DEC COBOL compiler treat all forms of identifers as references to the same object.

The DEC COBOL compiler performs transformations on identifiers with regard to both case and occurrences of hyphens and underscores. These transformed identifiers are visible in the listing file and in the symbol table of an image compiled with the -g flag. The rules for transformations are as follows:

Ladebug transforms all identifiers according to rule 2. When such a transformation causes a namespace conflict, an identifier is considered overloaded. When overloading occurs, it is necessary that you qualify an identifier to make it unique, as shown in Example 8-1, which demonstrates the application of the rules for transformation. Example 8-2 shows how Ladebug handles the COBOL identifiers.

Example 8-1 Sample COBOL Program

example.cob: 
* Ladebug Version 4.0 
* 
* Demonstrates usage of COBOL expressions with Ladebug 
* 
* There are three procedures in this file, namely cobol_example, 
* overloaded_name and b-2. 
* 
* (Rule #1) 
* In cobol_example, note the symbols B-2 and C_3: these two are given as 
* external and appear in the symbol table as B_2 and C_3 respectively. 
* C-3 and C_3 are equivalent as are D-3 and D_3 
* 
* (Rule #2) 
* In the procedure COBOL_EXAMPLE is the symbol overloaded-name, which appears 
* in the symbol table as OVERLOADED-NAME 
* 
* (Rule #3) 
* The procedure OverLoaded-NAME appears in the symbol table as 
* overloaded_name. 
 
* The procedure b-2 appears in the symbol table as b_2 
* 
* Note that there are three names referred to as B-2: 
* 
* "example.cob"`cobol_example`B_2    -- PIC X external 
* "example.cob"`overloaded_name`B-2  -- PIX 99 
* "example.cob"`b_2                  -- program id 
* 
 
IDENTIFICATION DIVISION. 
PROGRAM-ID. COBOL_EXAMPLE.          (1)
 
DATA DIVISION. 
WORKING-STORAGE SECTION. 
01 A_1 PIC X VALUE IS "1". 
01 B-2 PIC X             external.  (2)
01 C_3 PIC X             external. 
01 D-4 PIC X VALUE IS "4". 
01 overloaded-name pic 99.          (3)
 
PROCEDURE DIVISION. 
P0-lab. 
 DISPLAY "*** Ladebug COBOL Example ***". 
 MOVE "2" TO B_2. 
 MOVE "3" TO C-3. 
 DISPLAY "A_1 = " A_1. 
 DISPLAY "B-2 = " B-2. 
 DISPLAY "C_3 = " C_3.       (4)     
 DISPLAY "C-3 = " C-3. 
P0_lab. 
 DISPLAY "D-4 = " D-4.       (5)     
 DISPLAY "D_4 = " D_4. 
 CALL "Overloaded-Name".     (6)     
 CALL "B-2". 
 DISPLAY "***END Ladebug COBOL Example***". 
 STOP RUN. 
end program cobol-example. 
 
 
 
 
 
 
identification division. 
program-id. OverLoaded-NAME.        (6)
 
data division. 
working-storage section. 
01 b_2 pic 99 value is 12.          (7)
procedure division. 
beg1. 
        display "*** Overloaded-Name ***". 
 display "b_2 = " b-2.       (7)
 display "*** end of Overloaded-Name ***". 
end program overloaded-name. 
 
 
 
 
 
identification division. 
program-id. b-2.                    (8)
 
data division. 
working-storage section. 
procedure division. 
beg1. 
 
        display "*** b_2 ***". 
 display "*** end of b_2 ***". 
end program b-2. 


Previous Next Contents Index