H. Using the GNU C++ Debugger

Objectives

In this appendix you’ll learn:

Image  To use the run command to run a program in the debugger.

Image  To use the break command to set a breakpoint.

Image  To use the continue command to continue execution.

Image  To use the print command to evaluate expressions.

Image  To use the set command to change variable values during program execution.

Image  To use the step, finish and next commands to control execution.

Image  To use the watch command to see how a data member is modified during program execution.

Image  To use the delete command to remove a breakpoint or a watchpoint.

And so shall I catch the fly.

William Shakespeare

We are built to make mistakes, coded for error.

Lewis Thomas

What we anticipate seldom occurs; what we least expect generally happens.

Benjamin Disraeli

He can run but he can’t hide.

Joe Louis

It is one thing to show a man that he is in error, and another to put him in possession of truth.

John Locke

Outline

H.1 Introduction

In Chapter 2, you learned that there are two types of errors—compilation errors and logic errors—and you learned how to eliminate compilation errors from your code. Logic errors do not prevent a program from compiling successfully, but they can cause the program to produce erroneous results when it runs. GNU includes software called a debugger that allows you to monitor the execution of your programs so you can locate and remove logic errors.

The debugger is one of the most important program development tools. Many IDEs provide their own debuggers similar to the one included in GNU or provide a graphical user interface to GNU’s debugger. This appendix demonstrates key features of GNU’s debugger. Appendix G discusses the features and capabilities of the Visual Studio debugger. Our C++ Resource Center (www.deitel.com/cplusplus/) provides links to tutorials that can help you familiarize yourself with the debuggers provided with various other development tools.

H.2 Breakpoints and the run, stop, continue and print Commands

We begin our study of the debugger by investigating breakpoints, which are markers that can be set at any executable line of code. When program execution reaches a breakpoint, execution pauses, allowing you to examine the values of variables to help determine whether a logic error exists. For example, you can examine the value of a variable that stores the result of a calculation to determine whether the calculation was performed correctly. Note that attempting to set a breakpoint at a line of code that is not executable (such as a comment) will actually set the breakpoint at the next executable line of code in that function.

To illustrate the features of the debugger, we use class Account (Figs. H.1H.2) and the program listed in Fig. H.3, which creates and manipulates an object of class Account. Execution begins in main (lines 12–30 of Fig. H.3). Line 14 creates an Account object with an initial balance of $50.00. Account’s constructor (lines 10–22 of Fig. H.2) accepts one argument, which specifies the Account’s initial balance. Line 17 of Fig. H.3 outputs the initial account balance using Account member function getBalance. Line 19 declares a local variable withdrawalAmount which stores a withdrawal amount input by the user. Line 21 prompts the user for the withdrawal amount; line 22 inputs the withdrawalAmount. Line 25 uses the Account’s debit member function to subtract the withdrawalAmount from the Account’s balance. Finally, line 28 displays the new balance.

Fig. H.1 Header file for the Account class.

 1   // Fig.  H.1: Account.h
 2   // Definition of Account class.
 3
 4   class Account
 5   {
 6   public:
 7      Account( int ); // constructor initializes balance
 8      void credit( int ); // add an amount to the account balance
 9      void debit( int ); // subtract an amount from the account balance
10      int getBalance(); // return the account balance
11   private:
12      int balance; // data member that stores the balance
13   }; // end class Account

Fig. H.2 Definition for the Account class.

 1   // Fig. H.2: Account.cpp
 2   // Member-function definitions for class Account.
 3   #include <iostream >
 4   using std::cout;
 5   using std::endl;
 6
 7   #include "Account.h" // include definition of class Account
 8
 9   // Account constructor initializes data member balance
10   Account::Account( int initialBalance )
11   {
12      balance = 0; // assume that the balance begins at 0
13
14      // if initialBalance is greater than 0, set this value as the
15      // balance of the Account; otherwise, balance remains 0
16      if ( initialBalance > 0 )
17         balance = initialBalance;
18
19      // if initialBalance is negative, print error message
20      if ( initialBalance < 0 )
21         cout << "Error: Initial balance cannot be negative. " << endl;
22   } // end Account constructor
23
24   // credit (add) an amount to the account balance
25   void Account::credit( int amount )
26   {
27      balance = balance + amount; // add amount to balance
28   } // end function credit
29
30   // debit (subtract) an amount from the account balance
31   void Account::debit( int amount )
32   {
33      if ( amount <= balance ) // debit amount does not exceed balance
34         balance = balance - amount;
35

36      else // debit amount exceeds balance
37         cout << "Debit amount exceeded account balance. " << endl;
38   } // end function debit
39
40   // return the account balance
41   int Account::getBalance()
42   {
43      return balance; // gives the value of balance to the calling function
44   } // end function getBalance

Fig. H.3 Test class for debugging.

 1   // Fig. H.3: figH_03.cpp
 2   // Create and manipulate Account objects.
 3   #include <iostream>
 4   using std::cin;
 5   using std::cout;
 6   using std::endl;
 7
 8   // include definition of class Account from Account.h
 9   #include "Account.h"
10
11   // function main begins program execution
12   int main()
13   {
14      Account account1( 50 ); // create Account object
15
16      // display initial balance of each object
17      cout << "account1 balance: $" << account1.getBalance() << endl;
18
19      int withdrawalAmount; // stores withdrawal amount read from user
20
21      cout << " Enter withdrawal amount for account1: "; // prompt
22      cin >> withdrawalAmount; // obtain user input
23      cout << " attempting to subtract " << withdrawalAmount
24         << " from account1 balance ";
25      account1.debit( withdrawalAmount ); // try to subtract from account1
26
27      // display balances
28      cout << "account1 balance: $" << account1.getBalance() << endl;
29      return 0; // indicate successful termination
30   } // end main

In the following steps, you’ll use breakpoints and various debugger commands to examine the value of the variable withdrawalAmount declared in line 19 of Fig. H.3.

1.   Compiling the program for debugging. To use the debugger, you must compile your program with the -g option, which generates additional information that the debugger needs to help you debug your programs. To do so, type

g++ -g -o figJ_03 figJ_03.cpp Account.cpp

2.   Starting the debugger. Type gdb figJ_03 (Fig. H.4). The gdb command starts the debugger and displays the (gdb) prompt at which you can enter commands.

Fig. H.4 Starting the debugger to run the program.

$ gdb FigJ_03
GNU gdb 6.3-debian
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or 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.
This GDB was configured as "i486-linux-gnu"...Using host libthread_db
library "/ lib/tls/i686/cmov/libthread_db.so.1".

(gdb)

3.   Running a program in the debugger. Run the program through the debugger by typing run (Fig. H.5). If you do not set any breakpoints before running your program in the debugger, the program will run to completion.

Fig. H.5 Running the program with no breakpoints set.

(gdb) run
Starting program: /home/nuke/AppJ/FigJ_03
account1 balance: $50

Enter withdrawal amount for account1: 13

attempting to subtract 13 from account1 balance

account1 balance: $37

Program exited normally.
(gdb)

4.   Inserting breakpoints using the GNU debugger. Set a breakpoint at line 17 of FigJ_03.cpp by typing break 17. The break command inserts a breakpoint at the line number specified as its argument (i.e., 17). You can set as many breakpoints as necessary. Each breakpoint is identified by the order in which it was created. The first breakpoint is known as Breakpoint 1. Set another breakpoint at line 25 by typing break 25 (Fig. H.6). This new breakpoint is known as Breakpoint 2. When the program runs, it suspends execution at any line that contains a breakpoint and the debugger enters break mode. Breakpoints can be set even after the debugging process has begun. [Note: If you do not have a numbered listing for your code, you can use the list command to output your code with line numbers. For more information about the list command type help list from the gdb prompt.]

Fig. H.6 Setting two breakpoints in the program.

(gdb) break 17
Breakpoint 1 at 0x80486f6: file FigJ_03.cpp, line 17.
(gdb) break 25
Breakpoint 2 at 0x8048799: file FigJ_03.cpp, line 25.
(gdb)

5.   Running the program and beginning the debugging process. Type run to execute your program and begin the debugging process (Fig. H.7). The debugger enters break mode when execution reaches the breakpoint at line 17. At this point, the debugger notifies you that a breakpoint has been reached and displays the source code at that line (17), which will be the next statement to execute.

Fig. H.7 Running the program until it reaches the first breakpoint.

(gdb) run
Starting program: /home/nuke/AppJ/FigJ_03

Breakpoint 1, main () at FigJ_03.cpp:17
17         cout << "account1 balance: $" << account1.getBalance() << endl;
(gdb)

6.   Using the continue command to resume execution. Type continue. The continue command causes the program to continue running until the next breakpoint is reached (line 25). Enter 13 at the prompt. The debugger notifies you when execution reaches the second breakpoint (Fig. H.8). Note that figJ_03’s normal output appears between messages from the debugger.

Fig. H.8 Continuing execution until the second breakpoint is reached.

(gdb) continue
Continuing.
account1 balance: $50

Enter withdrawal amount for account1: 13

attempting to subtract 13 from account1 balance


Breakpoint 2, main () at FigJ_03.cpp:25
25         account1.debit( withdrawalAmount ); // try to subtract from
account1
(gdb)

7.   Examining a variable’s value. Type print withdrawalAmount to display the current value stored in the withdrawalAmount variable (Fig. H.9). The print command allows you to peek inside the computer at the value of one of your variables. This can be used to help you find and eliminate logic errors in your code. In this case, the variable’s value is 13—the value you entered that was assigned to variable withdrawalAmount in line 22 of Fig. H.3. Next, use print to display the contents of the account1 object. When an object is displayed with print, braces are placed around the object’s data members. In this case, there is a single data member—balance—which has a value of 50.

Fig. H.9 Printing the values of variables.

(gdb) print withdrawalAmount
$2 = 13
(gdb) print account1
$3 = {balance = 50}
(gdb)

8.   Using convenience variables. When you use print, the result is stored in a convenience variable such as $1. Convenience variables are temporary variables created by the debugger that are named using a dollar sign followed by an integer. Convenience variables can be used to perform arithmetic and evaluate boolean expressions. Type print $1. The debugger displays the value of $1 (Fig. H.10), which contains the value of withdrawalAmount. Note that printing the value of $1 creates a new convenience variable—$3.

Fig. H.10 Printing a convenience variable.

(gdb) print $1
$3 = 13
(gdb)

9.   Continuing program execution. Type continue to continue the program’s execution. The debugger encounters no additional breakpoints, so it continues executing and eventually terminates (Fig. H.11).

Fig. H.11 Finishing execution of the program.

(gdb) continue
Continuing.
account1 balance: $37

Program exited normally.
(gdb)

10.   Removing a breakpoint. You can display a list of all of the breakpoints in the program by typing info break. To remove a breakpoint, type delete, followed by a space and the number of the breakpoint to remove. Remove the first breakpoint by typing delete 1. Remove the second breakpoint as well. Now type info break to list the remaining breakpoints in the program. The debugger should indicate that no breakpoints are set (Fig. H.12).

Fig. H.12 Viewing and removing breakpoints.

(gdb) info break
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x080486f6 in main at FigJ_03.cpp:17
        breakpoint already hit 1 time
2   breakpoint     keep y   0x08048799 in main at FigJ_03.cpp:25
        breakpoint already hit 1 time
(gdb) delete 1
(gdb) delete 2
(gdb) info break
No breakpoints or watchpoints.
(gdb)

11.   Executing the program without breakpoints. Type run to execute the program. Enter the value 13 at the prompt. Because you successfully removed the two breakpoints, the program’s output is displayed without the debugger entering break mode (Fig. H.13).

Fig. H.13 Program executing with no breakpoints set.

(gdb) run
Starting program: /home/nuke/AppJ/FigJ_03
account1 balance: $50

Enter withdrawal amount for account1: 13

attempting to subtract 13 from account1 balance

account1 balance: $37

Program exited normally.
(gdb)

12.   Using the quit command. Use the quit command to end the debugging session (Fig. H.14). This command causes the debugger to terminate.

Fig. H.14 Exiting the debugger using the quit command.

(gdb) quit
$

In this section, you used the gdb command to start the debugger and the run command to start debugging a program. You set a breakpoint at a particular line number in the main function. The break command can also be used to set a breakpoint at a line number in another file or at a particular function. Typing break, then the filename, a colon and the line number will set a breakpoint at a line in another file. Typing break, then a function name will cause the debugger to enter the break mode whenever that function is called.

Also in this section, you saw how the help list command will provide more information on the list command. If you have any questions about the debugger or any of its commands, type help or help followed by the command name for more information.

Finally, you examined variables with the print command and remove breakpoints with the delete command. You learned how to use the continue command to continue execution after a breakpoint is reached and the quit command to end the debugger.

H.3 print and set Commands

In the preceding section, you learned how to use the debugger’s print command to examine the value of a variable during program execution. In this section, you’ll see how to use the print command to examine the value of more complex expressions. You’ll also learn the set command, which allows you to assign new values to variables. We assume you are working in the directory containing this appendix’s examples and have compiled for debugging with the -g compiler option.

1.   Starting debugging. Type gdb figJ_03 to start the GNU debugger.

2.   Inserting a breakpoint. Set a breakpoint at line 25 in the source code by typing break 25 (Fig. H.15).

Fig. H.15 Setting a breakpoint in the program.

(gdb) break 25
Breakpoint 1 at 0x8048799: file FigJ_03.cpp, line 25.
(gdb)

3.   Running the program and reaching a breakpoint. Type run to begin the debugging process (Fig. H.16). This will cause main to execute until the breakpoint at line 25 is reached. This suspends program execution and switches the program into break mode. The statement in line 25 is the next statement that will execute.

Fig. H.16 Running the program until the breakpoint at line 25 is reached.

(gdb) run
Starting program: /home/nuke/AppJ/FigJ_03
account1 balance: $50

Enter withdrawal amount for account1: 13

attempting to subtract 13 from account1 balance


Breakpoint 1, main () at FigJ_03.cpp:25
25         account1.debit( withdrawalAmount ); // try to subtract from
account1
(gdb)

4.   Evaluating arithmetic and boolean expressions. Recall from Section H.2 that once the debugger enters break mode, you can explore the values of the program’s variables using the print command. You can also use print to evaluate arithmetic and boolean expressions. Type print withdrawalAmount - 2. This expression returns the value 11 (Fig. H.17), but does not actually change the value of withdrawalAmount. Type print withdrawalAmount == 11. Expressions containing the == symbol return bool values. The value returned is false (Fig. H.17) because withdrawalAmount withdrawalAmount still contains 13.

Fig. H.17 Printing expressions with the debugger.

(gdb) print withdrawalAmount - 2
$1 = 11
(gdb) print withdrawalAmount == 11
$2 = false
(gdb)

5.   Modifying values. You can change the values of variables during the program’s execution in the debugger. This can be valuable for experimenting with different values and for locating logic errors. You can use the debugger’s set command to change a variable’s value. Type set withdrawalAmount = 42 to change the value of withdrawalAmount, then type print withdrawalAmount to display its new value (Fig. H.18).

Fig. H.18 Setting the value of a variable while in break mode.

(gdb) set withdrawalAmount = 42
(gdb) print withdrawalAmount
$3 = 42
(gdb)

6.   Viewing the program result. Type continue to continue program execution. Line 25 of Fig. H.3 executes, passing withdrawalAmount to Account member function debit. Function main then displays the new balance. Note that the result is $8 (Fig. H.19). This shows that the preceding step changed the value of withdrawalAmount from the value 13 that you input to 42.

Fig. H.19 Using a modified variable in the execution of a program.

(gdb) continue
Continuing.
account1 balance: $8

Program exited normally.
(gdb)

7.   Using the quit command. Use the quit command to end the debugging session (Fig. H.20). This command causes the debugger to terminate.

Fig. H.20 Exiting the debugger using the quit command.

(gdb) quit
$

In this section, you used the debugger’s print command to evaluate arithmetic and boolean expressions. You also learned how to use the set command to modify the value of a variable during your program’s execution.

H.4 Controlling Execution Using the step, finish and next Commands

Sometimes you’ll need to execute a program line by line to find and fix errors. Walking through a portion of your program this way can help you verify that a function’s code executes correctly. The commands in this section allow you to execute a function line by line, execute all the statements of a function at once or execute only the remaining statements of a function (if you have already executed some statements within the function).

1.   Starting the debugger. Start the debugger by typing gdb figJ_03.

2.   Setting a breakpoint. Type break 25 to set a breakpoint at line 25.

3.   Running the program. Run the program by typing run, then enter 13 at the prompt. After the program displays its two output messages, the debugger indicates that the breakpoint has been reached and displays the code at line 25. The debugger then pauses and wait for the next command to be entered.

4.   Using the step command. The step command executes the next statement in the program. If the next statement to execute is a function call, control transfers to the called function. The step command enables you to enter a function and study its individual statements. For instance, you can use the print and set commands to view and modify the variables within the function. Type step to enter the debit member function of class Account (Fig. H.2). The debugger indicates that the step has been completed and displays the next executable statement (Fig. H.21)—in this case, line 33 of class Account (Fig. H.2).

Fig. H.21 Using the step command to enter a function.

(gdb) step
Account::debit (this=0xbff81700, amount=13) at Account.cpp:33
33         if ( amount <= balance ) // debit amount does not exceed balance
(gdb)

5.   Using the finish command. After you have stepped into the debit member function, type finish. This command executes the remaining statements in the function and returns control to the place where the function was called. The finish command executes the remaining statements in member function debit, then pauses at line 28 in main (Fig. H.22). In lengthy functions, you may want to look at a few key lines of code, then continue debugging the caller’s code. The finish command is useful for situations in which you do not want to step through the remainder of a function line by line.

Fig. H.22 Using the finish command to complete execution of a function and return to the calling function.

(gdb) finish
Run till exit from #0  Account::debit (this=0xbff81700, amount=13) at
   Account.cpp:33
0x080487a9 in main () at FigJ_03.cpp:25
25         account1.debit( withdrawalAmount ); // try to subtract from account1
(gdb)

6.   Using the continue command to continue execution. Enter the continue command to continue execution until the program terminates.

7.   Running the program again. Breakpoints persist until the end of the debugging session in which they are set. So, the breakpoint you set in Step 2 is still set. Type run to run the program and enter 13 at the prompt. As in Step 3, the program runs until the breakpoint at line 25 is reached, then the debugger pauses and waits for the next command (Fig. H.23).

Fig. H.23 Restarting the program.

(gdb) run
Starting program: /home/nuke/AppJ/FigJ_03
account1 balance: $50

Enter withdrawal amount for account1: 13

attempting to subtract 13 from account1 balance


Breakpoint 1, main () at FigJ_03.cpp:25
25         account1.debit( withdrawalAmount ); // try to subtract from
account1
(gdb)

8.   Using the next command. Type next. This command behaves like the step command, except when the next statement to execute contains a function call. In that case, the called function executes in its entirety and the program advances to the next executable line after the function call (Fig. H.24). In Step 4, the step command enters the called function. In this example, the next command executes Account member function debit, then the debugger pauses at line 28.

Fig. H.24 Using the next command to execute a function in its entirety.

(gdb) next
28         cout << "account1 balance: $" << account1.getBalance() << endl;
(gdb)

9.   Using the quit command. Use the quit command to end the debugging session (Fig. H.25). While the program is running, this command causes the program to immediately terminate rather than execute the remaining statements in main.

Fig. H.25 Exiting the debugger using the quit command.

(gdb) quit
The program is running.  Exit anyway? (y or n) y
$

In this section, you used the debugger’s step and finish commands to debug functions called during your program’s execution. You saw how the next command can step over a function call. You also learned that the quit command ends a debugging session.

H.5 watch Command

The watch command tells the debugger to watch a data member. When that data member is about to change, the debugger will notify you. In this section, you’ll use the watch command to see how the Account object’s data member balance is modified during execution.

1.   Starting the debugger. Start the debugger by typing gdb figJ_03.

2.   Setting a breakpoint and running the program. Type break 14 to set a breakpoint at line 14. Then, run the program with the command run. The debugger and program will pause at the breakpoint at line 14 (Fig. H.26).

Fig. H.26 Running the program until the first breakpoint.

(gdb) break 14
Breakpoint 1 at 0x80486e5: file FigJ_03.cpp, line 14.
(gdb) run
Starting program: /home/nuke/AppJ/FigJ_03

Breakpoint 1, main () at FigJ_03.cpp:14
14         Account account1( 50 ); // create Account object
(gdb)

3.   Watching a class’s data member. Set a watch on account1’s balance data member by typing watch account1.balance (Fig. H.27). This watch is labeled as watchpoint 2 because watchpoints are labeled with the same sequence of numbers as breakpoints. You can set a watch on any variable or data member of an object currently in scope. Whenever the value of a watched variable changes, the debugger enters break mode and notifies you that the value has changed.

Fig. H.27 Setting a watchpoint on a data member.

(gdb) watch account1.balance
Hardware watchpoint 2: account1.balance
(gdb)

4.   Executing the constructor. Use the next command to execute the constructor and initialize the account1 object’s balance data member. The debugger indicates that the balance data member’s value changed, shows the old and new values and enters break mode at line 20 (Fig. H.28).

Fig. H.28 Stepping into the constructor.

(gdb) next
Hardware watchpoint 2: account1.balance

Old value = 0
New value = 50
Account (this=0xbfcd6b90, initialBalance=50) at Account.cpp:20
20         if ( initialBalance < 0 )
(gdb)

5.   Exiting the constructor. Type finish to complete the constructor’s execution and return to main.

6.   Withdrawing money from the account. Type continue to continue execution and enter a withdrawal value at the prompt. The program executes normally. Line 25 of Fig. H.3 calls Account member function debit to reduce the Account object’s balance by a specified amount. Line 34 of Fig. H.2 inside function debit changes the value of balance. The debugger notifies you of this change and enters break mode (Fig. H.29).

Fig. H.29 Entering break mode when a variable is changed.

(gdb) continue
Continuing.
account1 balance: $50

Enter withdrawal amount for account1: 13

attempting to subtract 13 from account1 balance

Hardware watchpoint 2: account1.balance

Old value = 50
New value = 37
0x0804893b in Account::debit (this=0xbfcd6b90, amount=13) at Account.cpp:34
34            balance = balance - amount;
(gdb)

7.   Continuing execution. Type continue—the program will finish executing function main because the program does not attempt any additional changes to balance. The debugger removes the watch on account1’s balance data member because the account1 object goes out of scope when function main ends. Removing the watchpoint causes the debugger to enter break mode. Type continue again to finish execution of the program (Fig. H.30).

Fig. H.30 Continuing to the end of the program.

(gdb) continue
Continuing.
account1 balance: $37

Watchpoint 2 deleted because the program has left the block in
which its expression is valid.
0xb7da0595 in exit () from /lib/tls/i686/cmov/libc.so.6
(gdb) continue
Continuing.

Program exited normally.
(gdb)

8.   Restarting the debugger and resetting the watch on the variable. Type run to restart the debugger. Once again, set a watch on account1 data member balance by typing watch account1.balance. This watchpoint is labeled as watchpoint 3. Type continue to continue execution (Fig. H.31).

Fig. H.31 Resetting the watch on a data member.

(gdb) run
Starting program: /home/nuke/AppJ/FigJ_03

Breakpoint 1, main () at FigJ_03.cpp:14
14         Account account1( 50 ); // create Account object
(gdb) watch account1.balance
Hardware watchpoint 3: account1.balance
(gdb) continue
Continuing.
Hardware watchpoint 3: account1.balance

Old value = 0
New value = 50
Account (this=0xbfd8eb90, initialBalance=50) at Account.cpp:20
20         if ( initialBalance < 0 )
(gdb)

9.   Removing the watch on the data member. Suppose you want to watch a data member for only part of a program’s execution. You can remove the debugger’s watch on variable balance by typing delete 3 (Fig. H.32). Type continue—the program will finish executing without reentering break mode.

Fig. H.32 Removing a watch.

(gdb) delete 3
(gdb) continue
Continuing.
account1 balance: $50

Enter withdrawal amount for account1: 13

attempting to subtract 13 from account1 balance

account1 balance: $37

Program exited normally.
(gdb)

In this section, you used the watch command to enable the debugger to notify you when the value of a variable changes. You used the delete command to remove a watch on a data member before the end of the program.

H.6 Wrap-Up

In this appendix, you learned how to insert and remove breakpoints in the debugger. Breakpoints allow you to pause program execution so you can examine variable values with the debugger’s print command, which can help you locate and fix logic errors. You used the print command to examine the value of an expression, and you used the set command to change the value of a variable. You also learned debugger commands (including the step, finish and next commands) that can be used to determine whether a function is executing correctly. You learned how to use the watch command to keep track of a data member throughout the scope of that data member. Finally, you learned how to use the info break command to list all the breakpoints and watchpoints set for a program and the delete command to remove individual breakpoints and watchpoints.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset