You can use this manual at your leisure to read all about the debugger. However, a handful of commands are enough to get started using the debugger. This chapter illustrates those commands.
The benchmark program Whetstone is frequently used to measure the performance of floating-point operations. We run Whetstone on the target to compare its performance with other computers. The workings of Whetstone are a bit of a mystery, but by using the debugger we can get an insight.
The first step is to compile the Whetstone source with the debug option switched on. There is no need to compile with minimal optimization since the debugger is able to cope with most optimizations.
Note that prefix should be replaced with the prefix for your product.
The code we wish to look at starts on line 306, just after the array e1 has been set up. Here is part of the Ada source file showing line 306 and some of the surrounding lines.
300 301 -- Module 2: computations with array elements 302 e1 (1) := 1.0; 303 e1 (2) := -1.0; 304 e1 (3) := -1.0; 305 e1 (4) := -1.0; 306 for i in 1 .. n2 loop 307 e1 (1) := (e1 (1) + e1 (2) + e1 (3) - e1 (4)) * t; 308 e1 (2) := (e1 (1) + e1 (2) - e1 (3) + e1 (4)) * t;
We start the debugger using the following command. You may use the -q option to suppress the banner:
$ prefix-gdb whetstone XGC target-ada Version 1.5 (debugger) Copyright (c) 1996, 2001, XGC Software. Based on gdb version 4.17.gnat.3.11 Copyright (c) 1998 Free Software Foundation... (gdb)
The easiest way to get to line 306 is to set a breakpoint on that line, then use the run command. Breakpoints are set using the break command. We can check what breakpoints are set using the info command.
(gdb) break whetstone.adb:306 Breakpoint 1 at 0xee2: file whetstone.adb, line 306. (gdb) info breakpoints Num Type Disp Enb Address What 1 breakpoint keep y 0x00000ee2 in whetstone at whetstone.adb:306 (gdb)
So far we have been working with the exec target. This is the executable file whetstone cited on the comand line that invoked the debugger. Using just this file, and no target at all, we can look at the values of symbols, inspect the source code, and the generated code, and check the values of static variables.
In order to run the program we must switch to a real or simulated target. The debugger supports both. The simulator target is called sim and a real target is called remote. The debugger will automatically switch to the simulator and load the program into the simulator if we enter the run command at this point.
(gdb) run Starting program: .../examples/whetstone Connected to the simulator. Loading sections: Idx Name Size VMA LMA File off Algn 0 .init 00000408 00000000 00000000 00001000 2**1 CONTENTS, ALLOC, LOAD, CODE 1 .text 00001890 00000408 00000408 00001408 2**1 CONTENTS, ALLOC, LOAD, CODE 2 .rdata 000003ce 00001c98 00001c98 00002c98 2**1 CONTENTS, ALLOC, LOAD, READONLY 3 .data 0000038a 00010000 00002066 00004000 2**1 CONTENTS, ALLOC, LOAD, DATA Start address 0x0 Transfer rate: 73600 bits in <1 sec. Whetstone: Floating point benchmark Breakpoint 1, whetstone () at whetstone.adb:306 306 for i in 1 .. n2 loop (gdb)
What we want to do now is see how the value of e1 changes as we go round the loop. We can print the initial value using the print command. Note that arrays (and structures) may be printed with a single command.
(gdb) print e1(1) $1 = 1 (gdb) print e1(2) $2 = -1 (gdb) print e1 $2 = (1 => 1, 2 => -1, 3 => -1, 4 => -1) (gdb)
We can then step through the program one line at a time using the next command. Like many other commands, the next command repeats when we press Enter. Therefore, after the first next command, we just hit Enter.
(gdb) next 307 e1 (1) := (e1 (1) + e1 (2) + e1 (3) - e1 (4)) * t; (gdb) enter 308 e1 (2) := (e1 (1) + e1 (2) - e1 (3) + e1 (4)) * t; (gdb) enter 309 e1 (3) := (e1 (1) - e1 (2) + e1 (3) + e1 (4)) * t; (gdb) enter 310 e1 (4) := (-e1 (1) + e1 (2) + e1 (3) + e1 (4)) * t; (gdb)
Let's check the value of e1. This time we'll use the abbreviation.
If we need to check the value of e1 each time round the loop, it is tedious to have to step through each line then type the print command at the end of the loop. Instead we can place a breakpoint at the end of the loop and use the continue command to execute to the end of the loop. Furthermore, we can use the display command to print the value of e1 each time the program stops.
(gdb) br Breakpoint 2 at 0xf2e: file whetstone.adb, line 310. (gdb) display e1 1: e1 = (1 => 0, 2 => -0.499975026, 3 => -0.749975085, 4 => -1)
Use the continue command to run the program to the next breakpoint. Then press Enter to repeat the continue command. Note that continue may be abbreviated to c.
(gdb) c Continuing. Breakpoint 2, whetstone () at whetstone.adb:310 310 e1 (4) := (-e1 (1) + e1 (2) + e1 (3) + e1 (4)) * t; 1: e1 = (1 => -0.0625123829, 2 => -0.468692422, 3 => -0.734320521, 4 => -1.12491918) (gdb) Enter Continuing. Breakpoint 2, whetstone () at whetstone.adb:310 310 e1 (4) := (-e1 (1) + e1 (2) + e1 (3) + e1 (4)) * t; 1: e1 = (1 => -0.0664326251, 2 => -0.466705739, 3 => -0.733313918, 4 => -1.13265347) (gdb) Enter
To finish the debugging session use the quit command. You may abbreviate quit to q.