An Introduction to Some GNAT Tools

Prof. Michael B. Feldman
Department of Electrical Engineering and Computer Science
The George Washington University
Washington, DC 20052
(202) 994-5919 (voice)
(202) 994-0227 (fax)
mfeldman@seas.gwu.edu (Internet)
http://www.seas.gwu.edu/faculty/mfeldman

GNAT is free software; you can redistribute it and/or modify it under terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNAT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANT ABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNAT; see file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.


The document serves as an introduction to some of the tools provided with the GNAT (GNU Ada 95) compilation system. This document does not replace the "official" GNAT User Guide, but rather selectively augments it with examples of tool use and some helpful hints. All these tools have many more options and flags than we can cover here; please refer to the GNAT User Guide for further details.

Using gnatmake

Overriding the GNAT default file-naming conventions

Using gdb to get a simple traceback

Tracing a Program with gdb

Using gnatf to get a cross reference

Using gnatk8



Using gnatmake

gnatmake is the GNAT tool that builds an executable program from a set of source files, typically an Ada main program and a set of library units like packages. gnatmake has many options, including compiler, binder, and linker options to be passed through to those tools, multidirectory compilation structures, and the like. Here we cover some of the most frequently-used options. Throughout, our annotations and explanations are in the typeface you are reading. Our command line input is shown like this:

sample command line

and the output is shown like this:

sample output line

Consider a program test_factorial.adb, a source file containing one nested subprogram, Factorial, which recursively computes the factorial of its positive input argument. We build an executable test_factorial with the command

gnatmake -v -g -gnatl test_factorial

We have used the three options

Here is the screen output from this command, with our annotations:

GNATMAKE 3.07 (960911) Copyright 1995 Free Software Foundation, Inc.
  "test_factorial.ali" being checked ...
  -> "test_factorial.adb" time stamp mismatch

test_factorial needs to be compiled; gnatmake invokes the compiler and displays the listing:

gcc -c -g -gnatl test_factorial.adb
 
GNAT 3.07 (960911) Copyright 1991-1996 Free Software Foundation, Inc.
 
Compiling: test_factorial.adb (source file time stamp: 1996-09-22 15:15:47)
 
     1. with Ada.Text_IO;
     2. with Ada.Integer_Text_IO;
     3. procedure Test_Factorial is
     4. ------------------------------------------------------------------
     5. --| Demonstrates the factorial function
     6. --| Author: Michael B. Feldman, The George Washington University
     7. --| Copyright 1996, Michael B. Feldman. All Rights Reserved.
     8. --| Last Modified: August 1996
     9. ------------------------------------------------------------------
    10.
    11.   Answer: Positive;
    12.
    13.   function Factorial (N : IN Positive) return Positive is
    14.
    15.   -- Computes the factorial of N (N!) recursively
    16.   -- Pre : N is defined
    17.   -- Post: returns N!
    18.
    19.     Result : Positive;
    20.
    21.   begin  -- Factorial
    22.
    23.     if N = 1 then
    24.       Result := 1;                   -- stopping case
    25.     else
    26.       Result := N * Factorial(N-1);  -- recursion
    27.     end if;
    28.
    29.     return Result;
    30.   end Factorial;
    31.
    32. begin -- Test_Factorial
    33.
    34.   Answer := Factorial(4);
    35.   Ada.Text_IO.Put(Item => "The value of 4! is ");
    36.   Ada.Integer_Text_IO.Put(Item => Answer, Width => 11);
    37.   Ada.Text_IO.New_Line;
    38.
    39. end Test_Factorial;
 
 39 lines: No errors

Successful compilation; gnatmake invokes the binder and linker.

gnatbind -x test_factorial.ali
gnatlink -g test_factorial.ali

Having built the executable, we now run it from the command line:

test_factorial

The value of 4! is 24

If you want to save the listing in a file, say, in test_factorial.lst, just redirect the output:

gnatmake -v -g -gnatl test_factorial >test_factorial.lst
 

IMPORTANT NOTE:

If your source file is in the Macintosh file system (as opposed to the MachTen Fast File System), and using Alpha or BBEdit to edit your file, when you save a modified file the modification is NOT noticed by gnatmake, so invoking gnatmake on such a file will produce an "up to date" message instead of a compilation. This is a minor inconsistency in the various tools' treatment of Mac file timestamps; it may get fixed in later releases. The workaround is to "touch" the modified file from the MachTen command line before invoking gnatmake, for example:

touch test_factorial.adb

 


Overriding the GNAT default file-naming conventions

GNAT requires that each source file contain only one compilation unit (see gnatchop in the GNAT Users Guide for details on how to split multi-unit files). GNAT prefers that each file name agree with the name of the unit in that file, e.g., Test_Factorial is in the file test_factorial.adb. Note that the file name is always in lower-case, and that the file extension should be .ads for a package spec and .adb otherwise.

These conventions are sometimes inconvenient, for example, when porting in Ada source code from another compiler with different conventions. It is possible to override these preferences, using a configuration file called gnat.adc. If this file is present in the current directory, gnatmake will use it to map the file names to the unit names. Let's look at a set of files making up a program to do rational-number arithmetic. Here is the contents of gnat.adc.

pragma Source_File_Name 
  (Unit_Name => Rationals, Spec_File_Name => "prog21.ads");
pragma Source_File_Name 
  (Unit_Name => Rationals, Body_File_Name => "prog22.adb");
pragma Source_File_Name 
  (Unit_Name => Rationals.IO, Spec_File_Name => "prog23.ads");
pragma Source_File_Name 
  (Unit_Name => Rationals.IO, Body_File_Name => "prog24.adb");
pragma Source_File_Name 
  (Unit_Name => Test_Rationals_1, Body_File_Name => "prog25.adb");

Rationals provide a simple rational number package; Rationals.IO provides Get and Put operations for rationals, and Test_Rationals_1 is a simple demonstration of the package. To get a listing of the rationals spec, we type

gnatmake -gnats -gnatl prog21.ads

(the -gnats option does syntax checking only)

gcc -c -gnats -gnatl prog21.ads
 
GNAT 3.07 (960911) Copyright 1991-1996 Free Software Foundation, Inc.
 
Checking: prog21.ads (source file time stamp: 1996-09-22 14:14:00)
 
     1. package Rationals is
     2. ------------------------------------------------------------------
     3. --|
     4. --| Specification of the abstract data type for representing
     5. --| and manipulating rational numbers.
     6. --| All rational quantities in this package are initialized
     7. --| to 0/1.
     8. --|
     9. --| Author: Michael B. Feldman, The George Washington University
    10. --| Copyright 1996, Michael B. Feldman. All Rights Reserved.
    11. --| Last Modified: August 1996.
    12. --|
    13. ------------------------------------------------------------------
    14.
    15.   type Rational is private;
    16.
    17.   ZeroDenominator: exception;
    18.
    19.   function "/" (X : Integer; Y : Integer) return Rational;
    20.   -- constructor:
    21.   -- Pre :   X and Y are defined
    22.   -- Post:   returns a rational number
    23.   --   If Y > 0, returns Reduce(X,Y)
    24.   --   If Y < 0, returns Reduce(-X,-Y)
    25.   -- Raises: ZeroDenominator if Y = 0
    26.
    27.   function "+"(R1 : Rational; R2 : Rational) return Rational;
    28.   -- dyadic arithmetic constructor:
    29.   -- Pre : R1 and R2 are defined
    30.   -- Post: returns the rational sum of R1 and R2
    31.
    32. private
    33. -- A record of type Rational consists of a pair of Integer values
    34. -- such that the first number represents the numerator of a rational
    35. -- number and the second number represents the denominator.
    36.
    37.   type Rational is record
    38.     Numerator  : Integer  := 0;
    39.     Denominator: Positive := 1;
    40.   end record;
    41. end Rationals;
 
 41 lines: No errors

and we do the same for the spec of the rational input/output package:

gnatmake -gnats -gnatl prog23.ads

gcc -c -gnats -gnatl prog23.ads
 
GNAT 3.07 (960911) Copyright 1991-1996 Free Software Foundation, Inc.
 
Checking: prog23.ads (source file time stamp: 1996-09-22 14:14:00)
 
     1. with Ada.Text_IO;
     2. package Rationals.IO is
     3. ------------------------------------------------------------------
     4. --| Specification of the input/output child package for Rationals
     5. --|
     6. --| Author: Michael B. Feldman, The George Washington University
     7. --| Copyright 1996, Michael B. Feldman. All Rights Reserved.
     8. ------------------------------------------------------------------
     9.
    10.   procedure Get (Item : out Rational);
    11.   -- Pre : None
    12.   -- Post: The first integer number read is the numerator of Item;
    13.   --       the second integer number is the denominator of Item.
    14.   --       A "/" between the two numbers is optional.
    15.   --       The Rational constructor "/" is called
    16.   --       to produce a rational in reduced form.
    17.
    18.   procedure Put (Item : in Rational);
    19.   -- Pre : Item is defined
    20.   -- Post: displays the numerator and denominator of Item.
    21.
    22. end Rationals.IO;
 
 22 lines: No errors

Now we are ready to build Test_Rationals_1:

gnatmake -g -v -gnatl -f prog25.adb

GNATMAKE 3.05 (960607) Copyright 1995 Free Software Foundation, Inc.
gcc -c -g -gnatl prog25.adb
 
GNAT 3.07 (960911) Copyright 1991-1996 Free Software Foundation, Inc.
 
Compiling: prog25.adb (source file time stamp: 1996-09-22 14:14:01)
 
     1. with Ada.Text_IO;
     2. with Rationals; use type Rationals.Rational;
     3. with Rationals.IO;
     4. procedure Test_Rationals_1 is
     5. ------------------------------------------------------------------
     6. --| Very rudimentary test of package Rationals and Rationals.IO
     7. --|
     8. --| Author: Michael B. Feldman, The George Washington University
     9. --| Copyright 1996, Michael B. Feldman. All Rights Reserved.
    10. --| Last Modified: July 1995
    11. ------------------------------------------------------------------
    12.
    13.   A: Rationals.Rational;
    14.   B: Rationals.Rational;
    15.   C: Rationals.Rational;
    16.   D: Rationals.Rational;
    17.   E: Rationals.Rational;
    18.   F: Rationals.Rational;
    19.
    20. begin -- Test_Rationals_1
    21.
    22.   A := 1/3;
    23.   B := 2/(-4);
    24.   Ada.Text_IO.Put(Item => "A = ");
    25.   Rationals.IO.Put(Item => A);
    26.   Ada.Text_IO.New_Line;
    27.   Ada.Text_IO.Put(Item => "B = ");
    28.   Rationals.IO.Put(Item => B);
    29.   Ada.Text_IO.New_Line;
    30.
    31.   -- Read in rational numbers C and D.
    32.   Ada.Text_IO.Put(Item => "Enter rational number C > ");
    33.   Rationals.IO.Get(Item => C);
    34.   Ada.Text_IO.Put(Item => "Enter rational number D > ");
    35.   Rationals.IO.Get(Item => D);
    36.   Ada.Text_IO.New_Line;
    37.
    38.   E := A + B;
    39.   Ada.Text_IO.Put(Item => "E = A + B is ");
    40.   Rationals.IO.Put(Item => E);
    41.   Ada.Text_IO.New_Line;
    42.
    43.   F := C + D;
    44.   Ada.Text_IO.Put(Item => "F = C + D is ");
    45.   Rationals.IO.Put(Item => F);
    46.   Ada.Text_IO.New_Line;
    47.
    48.   Ada.Text_IO.Put(Item => "A + E + F is ");
    49.   Rationals.IO.Put(Item => A + E + F);
    50.   Ada.Text_IO.New_Line;
    51.
    52. end Test_Rationals_1;
 
 52 lines: No errors
 
gcc -c -g -gnatl prog22.adb

gnatmake has discovered that Rationals must be compiled (no .ali or .o file was present). Note that gnatmake goes directly to the rationals body; GNAT compiles its spec "on the fly" and produces no listing of the spec. That is why we did the earlier syntax-check steps, just to get the listings.

GNAT 3.07 (960911) Copyright 1991-1996 Free Software Foundation, Inc.
 
Compiling: prog22.adb (source file time stamp: 1996-09-22 14:14:00)
 
     1. package body Rationals is
     2.
     3. ------------------------------------------------------------------
     4. --| Body of the abstract data type for representing
     5. --| and manipulating rational numbers.
     6. --|
     7. --| Author: Michael B. Feldman, The George Washington University
     8. --| Copyright 1996, Michael B. Feldman
     9. --| Last Modified: August 1996
    10. ------------------------------------------------------------------
    11.
    12.   -- local function GCD, not provided to clients
    13.
    14.   function GCD(M: Positive; N: Positive) return Positive is
    15.   -- finds the greatest common divisor of M and N
    16.   -- Pre: M and N are defined
    17.   -- Post: returns the GCD of M and N, by Euclid's Algorithm
    18.
    19.     R    : Natural;
    20.     TempM: Positive;
    21.     TempN: Positive;
    22.
    23.   begin -- GCD
    24.
    25.     TempM := M;
    26.     TempN := N;
    27.
    28.     R := TempM rem TempN;
    29.
    30.     while R /= 0 loop
    31.       TempM := TempN;
    32.       TempN := R;
    33.       R := TempM rem TempN;
    34.     end loop;
    35.
    36.     return TempN;
    37.
    38.   end GCD;
    39.
    40.   -- exported operations
    41.
    42.   function "/" (X : Integer; Y : Integer) return Rational is
    43.     G: Positive;
    44.   begin -- "/"
    45.
    46.     if Y = 0 then
    47.       raise ZeroDenominator;
    48.     end if;
    49.
    50.     if X = 0 then
    51.       return (Numerator => 0, Denominator => 1);
    52.     end if;
    53.
    54.     G := GCD(abs X, abs Y);
    55.     if Y > 0 then
    56.       return (Numerator => X/G, Denominator => Y/G);
    57.     else
    58.       return (Numerator => (-X)/G, Denominator => (-Y)/G);
    59.     end if;
    60.
    61.   end "/";
    62.
    63.   -- dyadic arithmetic operator
    64.
    65.   function "+"(R1 : Rational; R2 : Rational) return Rational is
    66.     N: Integer;
    67.     D: Positive;
    68.   begin -- "+"
    69.     N := R1.Numerator * R2.Denominator + R2.Numerator * R1.Denominator;
    70.     D := R1.Denominator * R2.Denominator;
    71.     return N/D;  -- compiler will use Rational constructor here!
    72.   end "+";
    73.
    74. end Rationals;
 
 74 lines: No errors

Similarly, gnatmake invokes a compilation for Rationals.IO.

gcc -c -g -gnatl prog24.adb
 
GNAT 3.07 (960911) Copyright 1991-1996 Free Software Foundation, Inc.
 
Compiling: prog24.adb (source file time stamp: 1996-09-22 14:14:00)
 
     1. with Ada.Text_IO;
     2. with Ada.Integer_Text_IO;
     3. package body Rationals.IO is
     4. ------------------------------------------------------------------
     5. --| Body of the input/output child package for Rationals
     6. --|
     7. --| Author: Michael B. Feldman, The George Washington University
     8. --| Copyright 1996, Michael B. Feldman. All Rights Reserved
     9. --| Last Modified: August 1996
    10. ------------------------------------------------------------------
    11.
    12.   -- input procedure
    13.
    14.   procedure Get (Item : out Rational) is
    15.
    16.     N: Integer;
    17.     D: Integer;
    18.     Dummy: Character;  -- dummy character to hold the "/"
    19.
    20.   begin -- Get
    21.
    22.     Ada.Integer_Text_IO.Get(Item => N);
    23.     Ada.Text_IO.Get  (Item => Dummy);
    24.     Ada.Integer_Text_IO.Get(Item => D);
    25.     Item := N/D;
    26.
    27.   end Get;
    28.
    29.   -- output procedure
    30.
    31.   procedure Put (Item : in Rational) is
    32.
    33.   begin -- Put
    34.
    35.     Ada.Integer_Text_IO.Put(Item => Item.Numerator, Width => 1);
    36.     Ada.Text_IO.Put(Item => '/');
    37.     Ada.Integer_Text_IO.Put(Item => Item.Denominator, Width => 1);
    38.
    39.   end Put;
    40.
    41. end Rationals.IO;
 
 41 lines: No errors

Finally, gnatmake invokes the binder and linker.

gnatbind -x prog25.ali
gnatlink -g prog25.ali

Now we execute the demonstration program several times:

prog25
 
A = 1/3
B = -1/2
Enter rational number C > 2/4
Enter rational number D > 9/6
 
E = A + B is -1/6
F = C + D is 2/1
A + E + F is 13/6
 
prog25
 
A = 1/3
B = -1/2
Enter rational number C > 0/1
Enter rational number D > 9/6
 
E = A + B is -1/6
F = C + D is 3/2
A + E + F is 5/3
 
prog25
 
A = 1/3
B = -1/2
Enter rational number C > 1/0
 
raised RATIONALS.ZERODENOMINATOR

Here we entered a zero for the denominator of a rational. This is not allowed mathematically, so the exception is raised (somewhere in the rationals package) and propagated out of the main program.

We can get a full traceback showing where the exception was raised and how it propagated, but we need gdb for that.


Using gdb to get a simple traceback

GNAT does not come with its own debugger, or even a built-in traceback facility. Instead, it depends upon the GNU debugger, gdb. Let's use gdb to get a traceback from our rationals demonstration. We type

gdb prog25

and we are placed in gdb's command processor. gdb's prompts are indicated by (gdb).

GDB is free software and you are welcome to distribute copies of it under certain conditions; type "show copying" to see the conditions. There is absolutely no warranty for GDB; type "show warranty" for details.

GDB 4.15.1.gnat.1.10

Copyright 1995 Free Software Foundation, Inc.

(gdb) break __gnat_unhandled_exception

We have indicated that we wish gdb to stop the program and accept more commands, if an unhandled exception is raised. The address of the breakpoint is given; this will, in general, vary from machine to machine and even execution to excution. The file a-raise.c is part of the GNAT runtime and not of concern to us here.

Breakpoint 1 at 0x17dec: file a-raise.c, line 65

Now we tell gdb to run the program. It will run normally, unless that breakpoint is reached.

(gdb) run

Starting program: prog25
 
Breakpoint 1 at 0x1fa328c: file a-raise.c, line 65.
A = 1/3
B = -1/2
Enter rational number C > 1 0
 
Breakpoint 1, __gnat_unhandled_exception (except=0x36abb58) at a-raise.c:65
a-raise.c:65: No such file or directory.

Here we stop at the breakpoint, because we entered that zero denominator. Ignore the last line about a-raise.c. We request a traceback (which gdb calls a backtrace):

(gdb) backtrace
 
#0  __gnat_unhandled_exception (except=0x36abb58) at a-raise.c:65
#1  0x1fa33c4 in __gnat_raise_nodefer_with_msg (except=0x36abb58)
#2  0x1fa3438 in __gnat_raise_nodefer (except=0x36abb58)
#3  0x1fa34cc in __gnat_raise (except=0x36abb58)
#4  0x1fa2510 in rationals."/" (x=1, y=0) at prog22.adb:47
#5  0x1fa288c in rationals.io.get (item={numerator = 0, denominator = 1})
    at prog24.adb:25
#6  0x1fa2b08 in test_rationals_1 () at prog25.adb:33
#7  0x1f8b64c in main (argc=1, argv=0x1f8a3ec, envp=0x1f8a3f4) at b_prog25.c:40
#8  0x1f8b4e8 in __start (=0x4186001c, =0x81620008, =0x1)
#9  0x1f8b4a0 in __start (=0x1f8a59f, =0x1f8a5c6, =0x1f8a5d1)

Refer back to the listings above. The interesting part of the traceback, lines 4-6, shows that the exception was raised in the function "/" at line 22 of Rationals, which was called from the procedure Get at line 25 of Rationals.IO, which in turn was called from line 33 of Test_Rationals_1. The first four traceback lines, and the last 3 lines, give trace information from the GNAT runtime system. Normally you can ignore these lines.

(gdb) quit

The program is running. Quit anyway (and kill it)? (y or n) y


Tracing a Program with gdb

We can show some more gdb commands by returning to the program test_factorial. Here we will break not on an exception, but every time the Factorial function is called. Since Factorial is recursive, we will stop at every new level of recursion.

gdb test_factorial
 
GDB is free software and you are welcome to distribute copies of it
 under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 4.15.1.gnat.1.10, Copyright 1995 Free Software Foundation, Inc.
 

First we stop at the first executable statement of the main program:

(gdb) break test_factorial
Breakpoint 1 at 0x16ee4: file test_factorial.adb, line 34.

now we set a break for each time we call Factorial

(gdb) break factorial
Breakpoint 2 at 0x16dd0: file test_factorial.adb, line 23.
 
(gdb) run
Starting program: test_factorial
Breakpoint 1 at 0x2f6ef24: file test_factorial.adb, line 34.
Breakpoint 2 at 0x2f6ee10: file test_factorial.adb, line 23.
 
Breakpoint 1, test_factorial () at test_factorial.adb:34
34        Answer := Factorial(4);

and we continue the run

(gdb) continue
Continuing.
 
Breakpoint 2, test_factorial.factorial (n=4) at test_factorial.adb:23
23          if N = 1 then

Now we will set a watchpoint on the variable Result, so that the program will stop every time Result acuires a new value.

(gdb) watch result
Watchpoint 3: test_factorial.factorial::result
 
(gdb) continue
Continuing.
Watchpoint 3: test_factorial.factorial::result
 
Old value = 57185676
New value = 57179476
0x1efec48 in test_factorial.factorial (n=32402616) at test_factorial.adb:13
13        function Factorial (N : IN Positive) return Positive is

The huge values (which vary from execution to execution) suggest that Result is uninitialized at this point. This is true.

(gdb) continue
Continuing.
 
Breakpoint 2, test_factorial.factorial (n=3) at test_factorial.adb:23
23          if N = 1 then
 
(gdb) continue
Continuing.
Breakpoint 2, test_factorial.factorial (n=2) at test_factorial.adb:23
23          if N = 1 then
 
(gdb) continue
Continuing.
Watchpoint 3: test_factorial.factorial::result
 
Old value = 57179476
New value = 0
0x1efec48 in test_factorial.factorial (n=32402440) at test_factorial.adb:13
13        function Factorial (N : IN Positive) return Positive is
 
(gdb) continue
Continuing.
Breakpoint 2, test_factorial.factorial (n=1) at test_factorial.adb:23
23          if N = 1 then
 
(gdb) continue
Continuing.
Watchpoint 3: test_factorial.factorial::result
 
Old value = 0
New value = 1
0x1efec64 in test_factorial.factorial (n=1) at test_factorial.adb:24
24            Result := 1;                   -- stopping case

Now we've recursed all the way down, and start back up

(gdb) continue
Continuing.
Watchpoint 3: test_factorial.factorial::result
 
Old value = 1
New value = 57179476
0x1efed18 in test_factorial.factorial (n=2) at test_factorial.adb:29
29          return Result;
 
(gdb) continue
Continuing.
Watchpoint 3: test_factorial.factorial::result
 
Old value = 57179476
New value = 2
test_factorial.factorial (n=2) at test_factorial.adb:29
29          return Result;
 
(gdb) continue
Continuing.
Watchpoint 3: test_factorial.factorial::result
 
Old value = 2
New value = 57179476
0x1efed18 in test_factorial.factorial (n=3) at test_factorial.adb:29
29          return Result;
 
(gdb) continue
Continuing.
Watchpoint 3: test_factorial.factorial::result
 
Old value = 57179476
New value = 6
test_factorial.factorial (n=3) at test_factorial.adb:29
29          return Result;
 
(gdb) continue
Continuing.
Watchpoint 3: test_factorial.factorial::result
 
Old value = 6
New value = 57185676
0x1efed18 in test_factorial.factorial (n=4) at test_factorial.adb:29
29          return Result;
 
(gdb) continue
Continuing.
Watchpoint 3: test_factorial.factorial::result
 
Old value = 57185676
New value = 24
test_factorial.factorial (n=4) at test_factorial.adb:29
29          return Result;
 
(gdb) continue
Continuing.
Watchpoint 3 deleted because the program has left the block in
which its expression is valid.
0x1efecf8 in test_factorial.factorial (n=4) at test_factorial.adb:29
29          return Result;
 
(gdb) continue
Continuing.
The value of 4! is          24
 
Program exited normally
 

Refer to the GNAT documents for a full set of documentation on gdb. gdb also provides fairly useful on-line help:

(gdb) help

List of classes of commands:
running -- Running the program
stack -- Examining the stack
data -- Examining data
breakpoints -- Making program stop at certain points
files -- Specifying and examining files
status -- Status inquiries
support -- Support facilities
user-defined -- User-defined commands
aliases -- Aliases of other commands
obscure -- Obscure features
internals -- Maintenance commands
 
Type "help" followed by a class name for a list of commands in that class.
Type "help" followed by command name for full documentation.
Command name abbreviations are allowed if unambiguous.

 

Using gnatf to get a cross reference

Suppose we wish to know, for a given program, all its declarations and all the declarations it uses from the packages it WITHs, and where (which lines) these are referenced. Looking again at our rationals demonstration, we type

gnatf -x6 prog25.adb

gnatf stores the cross reference information in the file X.ref, so let's look at its contents:

Here we see the variables declared in Test_Rationals_1, and where in that program each is used (line and character position within line).

cat X.ref
 
%% prog25.adb           960922141401 %%
test_rationals_1 procedure 4:11
a variable 13:3
 prog25.adb {22:3 25:28 38:8 49:28}
b variable 14:3
 prog25.adb {23:3 28:28 38:12}
c variable 15:3
 prog25.adb {33:28 43:8}
d variable 16:3
 prog25.adb {35:28 43:12}
e variable 17:3
 prog25.adb {38:3 40:28 49:32}
f variable 18:3
 prog25.adb {43:3 45:28 49:36}

The main program calls some procedures from Ada.Text_IO

-- /usr/local/adainclude/a-textio.ads 960625050333 --
text_io package 30:13
 prog25.adb {1:10 24:7 26:7 27:7 29:7 32:7 34:7 36:7 39:7 41:7 44:7 46:7 48:7
  50:7}
text_io.new_line procedure 141:14
 prog25.adb {26:15 29:15 36:15 41:15 46:15 50:15}
text_io.put procedure 217:14
 prog25.adb {24:15 27:15 32:15 34:15 39:15 44:15 48:15}
 
-- /usr/local/adainclude/ada.ads 960625050300 --
ada package 18:9
 prog25.adb {24:3 26:3 27:3 29:3 32:3 34:3 36:3 39:3 41:3 44:3 46:3 48:3 50:3}
3}

and from Rationals

-- prog21.ads           960922141400 --
rationals package 1:9
 prog25.adb {2:6 2:26 13:6 14:6 15:6 16:6 17:6 18:6 25:3 28:3 33:3 35:3 40:3 45
 :3 49:3}
rational private_type 15:8 37:8
 prog25.adb {2:36 13:16 14:16 15:16 16:16 17:16 18:16}
"/" function 19:12
 prog25.adb {22:9 23:9}
"+" function 27:12
 prog25.adb {38:10 43:10 49:34 49:30}

and from Rationals.IO

-- prog23.ads           960922141400 --
io package 2:19
 prog25.adb {3:16 25:13 28:13 33:13 35:13 40:13 45:13 49:13}
io.get procedure 10:13
 prog25.adb {33:16 35:16}
io.put procedure 18:13
 prog25.adb {25:16 28:16 40:16 45:16 49:16}


Using gnatk8

We saw above how to override the GNAT file-naming conventions using a configuration file. But suppose we prefer to follow GNAT's preferences. We must name our files according to the units they contain. This can cause a problem if a unit's name is longer than our computer's maximum name length. For example, the Apple Macintosh has a file-name limit of 31 characters. Because our GNAT file names all end with a dot and a 3-letter extension, effectively we have a 27-character limit on the file name.

For systems with limits on file names, GNAT has an algorithm (krunch) for "crunching" its preferred file names down to the limit. On the Mac, if we add the flag -gnatk27 to a gnatmake invocation, GNAT will assume that all source file names follow the krunch algorithm for 27 characters. The algorithm is a bit involved; it is documented a bit in the GNAT Users Guide. Suffice it to say that if the file name has 27 characters or less, it is used without change.

Suppose the file name is long. How do we determine its krunched name? The tool gnatk8 gives us this capability. (This is an odd name; it comes from the fact that file names in DOS or OS/2 FAT file systems are 8 characters or less; the tool was developed originally for those systems.)

Given a unit

Very_Long_Unit_Name.Long_Child_Package_Name

stored in a file some_file.adb. We can rename this file correctly on the Mac in two steps. First, ask gnatk8 what the name should be:

gnatk8 Very_Long_Unit_Name.Long_Child_Package_Name 27

verlonuninamlonchilpackname

then rename the file accordingly

mv some_file.adb verlonuninamlonchilpackname.adb