What is GNAT?
What is GNAT-Mac?
The GNAT-Mac Development Project
What is Ada?
A1.1 Using gnatmake
A1.2 Overriding the GNAT default file-naming conventions
A1.3 Using gdb to get a simple traceback
A1.4 Tracing a Program with gdb
A1.5 Using gnatf to get a cross reference
A1.6 Using gnatk8
ACT maintains a site that holds the latest versions of the Macintosh
compilers and all documentation at:
or log in to: ftp://gnat-mac.com as
user pubmcada, no password, and cd to /usr/users/macada/public.
ACT provides GNAT compilers for all platforms (including the Mac) at this
site:
As of this writing, the relevant files are in directories mac68k and
powermac.
For other mirror sites, see the link "FTP and Mirror Sites" on
the ACT Home Page, http://www.gnat.com.
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
gnatinfo.txt, the "official" GNAT user manual, 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 shall cover here;
please refer to gnatinfo.txt for further details.
sample command lineand the output is shown like this:
sample output lineConsider 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 3.05 (960607) Copyright 1995 Free Software Foundation, Inc. "test_factorial.ali" being checked ... -> "test_factorial.adb" time stamp mismatch test_factorial needs to be compiled; invoke the compiler and display the listing. gcc -c -g -gnatl test_factorial.adb GNAT 3.05 (960607) 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 errorsSuccessful compilation; invoke the binder and linker.
Now we run the executable:gnatbind -x test_factorial.ali gnatlink -g test_factorial.ali
./test_factorial The value of 4! is 24
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:
GNAT 3.05 (960607) 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
GNAT 3.05 (960607) 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
GNATMAKE 3.05 (960607) Copyright 1995 Free Software Foundation, Inc. gcc -c -g -gnatl prog25.adb GNAT 3.05 (960607) 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
GNAT 3.05 (960607) 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
gcc -c -g -gnatl prog24.adb
GNAT 3.05 (960607) 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 errorsFinally, gnatmake invokes the binder and linker.
./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.ZERODENOMINATORHere 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.
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_exceptionWe 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 execution. 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 65Now 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) at a-raise.c:108 #2 0x1fa3438 in __gnat_raise_nodefer (except=0x36abb58) at a-raise.c:120 #3 0x1fa34cc in __gnat_raise (except=0x36abb58) at a- raise.c:130 #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
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 thenNow we will set a watchpoint on the variable Result, so that the program will stop every time Result acquires 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 isThe 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 caseNow 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 normallyRefer 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.
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}
Very_Long_Unit_Name.Long_Child_Package_Namestored 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 verlonuninamlonchilpacknameThen rename the file accordingly:
mv some_file.adb verlonuninamlonchilpackname.adb