This can be useful in helping you understand a program and to find
typos. For example, suppose you had the following:

cout << "The sum is: << sum << endl;

when it is color-coded:

cout << "The sum is: << sum << endl;

it displays the entire line after cout << ( in the
color used for a string literal. Since the variable sum
and the manipulator endl are obviously not intended to be
part of the string literal, it's easy to see there is an error, a
missing quote (").

As another example, suppose you are doing a science project on the
properties of materials. You are writing a program that keeps track of
properties of test objects, for example:

To load the file, choose Open File... from the Emacs File
menu. When it prompts you with:

Find file: curr-dir/

(where curr-dir is your current directory), type in the name of
the file, giving:

Find file: curr-dir/sum1.cpp

and press <Return>.

Aside:
The tilde (~) is shorthand for your home directory in many
programs and at the UNIX prompt. Thus, tilde (~) will
appear at the beginning of what Emacs lists as your current
directory if it is under your home directory.

You should now see the source code in Emacs. Note that since we have
loaded C++ code, Emacs has gone into C++ mode. Emacs knows it is
editing C++ code because the filename ends in .cpp.

Aside:
It may also recognize other common C++ file extensions like .cc.
For files ending in .c or .h, Emacs will go
into a similar C mode. Even though a header file (.h)
might have either C or C++ code, Emacs cannot tell the difference.

C++ Menu

Note that when you are in C++ mode in Emacs, there is an additional
menu named C++, with commands for navigating and editing C++
programs.

Aside:
A very similar C menu will appear in C mode.

Let's use one of the C++ menu's commands. In the Emacs window,
put the cursor at the end of the first line that uses cout:

cout << "Enter how many numbers I will sum: ";

If you now choose Forward Statement from the C++ menu, it
will go to the next statement, which is the one using cin:

cin >> howmany;

Aside: Roughly, a statement is something that ends in a
semi-colon (;), which is a simple statement.
There are also compound statements--all of the stuff in a block
(i.e., between braces, { and }) forms a
single compound statement.

You might use the Forward Statement command to advance through
statements in a program when you cannot easily tell where statements
begin and end.

Automatic Indentation

Another feature you can use when Emacs is in C++ mode is automatic
indentation. You can use this before or after the fact. In other
words, you can press the <Tab> key before you type a
line of code for it to indent to the proper place. Or, you can press
the <Tab> key while on a line, to fix its
indentation after the fact.

You'll want to explore the other features that Emacs gives you in C++
mode.

Don't forget to save your changes when you are done by using Save
Buffer from the Emacs Files menu. Shut down Emacs by choosing
Exit Emacs from the Emacs Files menu.

Using multiple buffers inside Emacs:

While working on a program, we may need to edit some source code,
compile and run it, edit other files and so on. There is no need
to start up and shut down Emacs each time we need to go back to the UNIX
prompt or need to load a different file. Instead, using features of
UNIX and Emacs, we can leave Emacs up during our entire login session.

First, we should take care to start up Emacs as:

% emacs &

By using the ampersand (&) at the end of the
command, we'll get a UNIX prompt back right away, where we can type
more UNIX commands. Without the &, the UNIX window
waits for Emacs to exit before it will let us type more commands.

Note:
Use & at the end of any UNIX command that brings up its own
window and runs for a while.

Note that Emacs has split its window into 2 parts (or subwindows),
each with the same file in it:

Then, click in the lower window, and use the Open File...
command (again, from the Files menu) to load avg1.cpp
in the lower window.

We can now click in the 2 subwindows to edit either one.

Suppose we want to spent some time on sum1.cpp, so we want
it to be the only window. We can do so by clicking in the upper window
(where sum1.cpp is loaded) and the choosing One Window
from the Emacs Files menu.

Finally, suppose we need avg1.cpp back. Just click in the
Emacs subwindow where you want it (there is only one now) and choose
avg1.cpp from the Buffers menu.

Until we exit Emacs, we can switch between loaded files in this way.

Compiling inside Emacs:

Not only can we compile programs at the UNIX prompt, but we can also
compile them inside of Emacs. Compiling programs while inside Emacs
makes it very easy to go through the source code and look at what
caused the errors and warnings reported by the compiler.

(If you don't already have that file, download it into your current
directory now.)

If you are not already running Emacs, start it up:

emacs &

To compile while in Emacs, use the Emacs command:

<Esc> x compile

At the bottom of the Emacs screen, it will ask you what UNIX command
to use for compilation. The default is make -k
(make is a separate topic), so erase that and type whatever
compilation command you'd use at the UNIX prompt:

g++ -o total sum1.cpp

Note that we told g++ to name the executable total.

Aside:
The code you are compiling should be in the same directory as the one in
which you started up Emacs.

Note that Emacs has split its window into 2 parts (or subwindows),
one of which contains the output of the attempt to compile the program:

This compilation window contains all the usual output from
the compilation process, including some compiler warnings/errors:

sum1.cpp: In function `int main()':
sum1.cpp:21: parse error before `float'
sum1.cpp:28: `O' undeclared (first use this function)
sum1.cpp:28: (Each undeclared identifier is reported only once
sum1.cpp:28: for each function it appears in.)
sum1.cpp:36: `sum' undeclared (first use this function)
sum1.cpp:39: confused by earlier errors, bailing out

We could search through the source code in an another Emacs subwindow to
examine and fix the errors, but there is an easier way:

Click in the compilation window (this is the one where the
compilation errors appeared). Note that a new menu appears, labeled
Compile.

Pull down the menu to look at its contents...

Remember, Emacs has special modes depending on what it is
doing. This menu appears when you are in a compilation window.

Choose First Error from the
Compile menu. Note that it automatically loads the
source code containing the error in the other Emacs subwindow (if it
wasn't already there) and places the cursor on the right line.
What is the error? Fix it.

Now, click in the compilation window again to get the
Compile menu back and choose Next
Error from the menu this time.
Once it is at the next error, determine the error and fix
it.

Since we fixed the first 2 errors, let's recompile the program and see
if what we fixed was causing the other error messages (i.e., errors
often cause other errors).

Bring up the Compile menu again, and choose
Recompile. Note that Emacs knows that you should save
the file you are about to recompile, and asks you to do so (choose
Yes). Emacs will use the same command we typed originally to
recompile.

If you corrected the first 2 errors properly, the program should
recompile successfully.

Since we are done with the compilation window for now, let's get rid of
it. Click in the Emacs subwindow that has the source code
sum1.cpp and then choose One Window
from the Emacs Files menu. We can bring back the
compilation window when needed (during this session with
Emacs), by choosing it from the Buffers menu.

Go to the UNIX prompt and run the executable total that was
created if you like.

Debugging inside Emacs:

For this example, we'll use a program that calculates an average,
avg1.cpp.

(If you don't already have that file, download it into your current
directory now.)

If you are not already running Emacs, start it up:

emacs &

Then, compile the program under Emacs. Remember to:

Use <Esc> x compile

Erase the default, make -k

Type in the proper compilation command (we'll give it an executable
name other than a.out):

g++ -o avg -g avg1.cpp

Note: We've added a new flag -g. If you want to be
able to debug a program, you'll have to add this -g option when
you compile it.

The program should compile without any errors or warnings.

Since we will be running the executable several times to debug it,
download this data file numdata.

Aside:
The data file tells the program that there are 4 numbers to
average, which are: 10, 20, 30,
and 40.

You'll notice that the program produces a nice Segmentation
fault. This calls for using the debugger, Gdb! We could run Gdb
from the UNIX prompt, but it is more useful to run it under Emacs.

Running Gdb under Emacs:

Let's start up Gdb under Emacs:

Select the compilation window by clicking in it
(we'll reuse this window for Gdb)

Type <Esc> x gdb

When it prompts you for the command to use to start Gdb:

Run gdb (like this): gdb

complete the command with the name of the executable, as in:

Run gdb (like this): gdb avg

Gdb should now be running in that window. Let's run our executable
avg under Gdb.

If we just wanted to run the executable without using a data file
(i.e., the user types in needed input), we could just type "run".
However, since we want to use our data file, numdata, we
should use input redirection, as in:

The output of the program is shown, just like when the program was run
at the UNIX prompt. In fact, we still get the Segmentation
fault. What's really nice about Gdb, however, is that it gives us
additional information, telling us where the Segmentation
fault occurred.

What may happen, as in this case, is that the Seg fault occurs not in
code you wrote, but in some library you used. (Note that it may have
loaded that nasty library code in the other Emacs subwindow.)

Examining the calling chain:

Although the Seg fault occurred in library code, it was most likely
still caused by an error on your part. We need to know how the
program got to that library function. To display the calling
chain, i.e., the sequence of function calls that lead to the
current point in the program, use:

Aha! Now we see that the problem was caused by the code at line 44 in
avg1.cpp (i.e., in main()).

We could load the source code into Emacs and go to line 44 (use
<Esc> x goto-line perhaps) and see what is there.
Instead, however, we can go back up the calling chain until we
are in our code. To do so, use the Gdb up command until we're
in main():

(gdb) up
#1 0x15f34 in streambuf::vscan (this=0x32fdc, fmt0=0x22640 "%g",
ap=0xeffff894, stream=0x32e84) at /csa/src/egcs-1.1.2/libio/sbscan.cc:33
(gdb) up
#2 0x15e50 in istream::scan (this=0x32e7c, format=0x22640 "%g")
at /csa/src/egcs-1.1.2/libio/isscan.cc:34
(gdb) up
#3 0x132bc in istream::operator>> (this=0x32e7c, x=@0xadfb2020)
at /csa/src/egcs-1.1.2/libio/iostream.cc:358
(gdb) up
#4 0x120d4 in main () at avg1.cpp:44

Conveniently, Emacs has loaded the source code (avg1.cpp)
in the other subwindow and is pointing (with an arrow, =>)
to the offending line, i.e., where the program stopped because of the
Seg fault.

Since the line contains an array access, perhaps the problem is an
out of range array index? We can display the value of index variable
i by using the Gdb print command:

(gdb) print i
$1 = -276903488

It's now obvious that i has an incorrect value. Find
the source of this problem and then fix it.

With that error fixed, we should recompile. While the cursor is in the
source code subwindow, call up the compilation window...Do this
by bringing back its buffer, i.e., choose the *compilation*
buffer from the Buffers menu:

Aside: Note the *gud-avg* listing for gdb
running on avg.

After bringing up the compilation window, choose
Recompile from the Compile menu. Note that it will
prompt you to save the edited source code, which you want to do. Make
sure that everything compiles ok.

Now, let's debug this new version of the executable. To get back to
Gdb, click in Emacs' gdb window after the (gdb) prompt:

We need to re-run the executable; however, we don't want to have to
type the redirection stuff every time. So, first do:

(gdb) set args < numdata

This tells Gdb to use "< numdata" as the argument to the run
command.

Then, run the program:

(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y

It will ask you if you want to restart the program (remember, we were
already running it and it Seg faulted). Just say y.

`yourdir/avg' has changed; re-reading symbols.
Starting program: yourdir/avg < numdata
Enter how many numbers I will average: Enter number: Enter number: Enter number\
:Enter number: The average is: 0
Thank you for using the averager!
Program exited normally.

Notice that Gdb automatically notices that there is a new version
(i.e., we just recompiled it) of the executable. Once it loads in the
new version of the executable, it will run it on the data file.

What's nice is that the Segmentation fault is now gone,
and the "Program exited normally." However, we now seem to have
a logic error since the average shouldn't be zero.

Stopping the program while it is running:

A main feature of a debugger is that we can tell it to stop a program
while it is running so that we can examine variables, etc.

The first thing we might check to find this error is to make sure the
numbers are read into our program properly.

Bring the source code back:

Click in the compilation window

Choose avg1.cpp from the Buffers menu

Now scroll to the line just after when the numbers are read in,
i.e., go to:

cout << "The average is: " << avgNumbers(numbers, howmany) << endl;

Note this statement's line number (listed at the bottom of the Emacs
subwindow with the source code). It should be line 47, but might be
something else if you added blank lines, etc. This line would be a
good place to stop the program and then check all the numbers. We can
tell Gdb to stop the program at this line by setting a
breakpoint.

Go back to the Gdb window (i.e., click in it after the prompt) and
type:

(gdb) break 47
Breakpoint 1 at 0x120ec: file avg1.cpp, line 47.

Aside: Gdb assumes the line number refers to a line in the
source code file from which it last performed a statement. Since,
right now, our executable is only made up of one source code file, this
doesn't matter.

However, if you needed to refer to a line in another source code file,
you'd use the form "filename:line" as in:

Continuing program once it has been stopped:

The program continued and then should have stopped in
avgNumbers() like we asked it to.

Note:
It displays the values of the parameters of the function
avgNumbers() in which it stopped. Since
numbers is an array, it displays its address.

As usual, it is following the code in the source code window.

We may want to see what happens after it performs the statement:

int sum = sumNumbers(numbers, howmany);

To just perform this statement and have the program stop again, use the
next command. Then, we can examine the sum with print:

(gdb) next
(gdb) print sum
$3 = 0

A sum of zero is clearly wrong. This implies that function
sumNumbers() is probably not calculating the sum correctly.
Let's explore this theory...

Start by re-running the program under Gdb:

(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: yourdir/avg < numdata
Enter how many numbers I will average: Enter number: Enter number:
Breakpoint 2, avgNumbers (numbers=0xeffff920, howmany=4) at avg1.cpp:59

We again stop at our breakpoint in avgNumbers(). This time,
instead of using next to perform the call to
sumNumbers(), let's use step, so that we step
into that function:

(gdb) step
sumNumbers (numbers=0xeffff920, howmany=4) at avg1.cpp:65

Now that we are in sumNumbers(), we see that the variable
we'll want to examine is sum. Rather than using
print to view its value as we go through the function, we can
use the display command:

(gdb) display sum
1: sum = 0

which will display the value of that variable every time the program
stops.

We'll want to go through the loop statement by statement and see how
sum changes. First, go to the loop with:

(gdb) next
1: sum = 0

Now, start the loop with:

(gdb) next
1: sum = 0

Since this is a for loop, it has done what part(s) of the loop?

Now, let's do the assignment statement in the loop body:

(gdb) next
1: sum = 0

Hmmm...The sum did not change (we want it to!)

Let's continue the loop for another iteration:

(gdb) next
1: sum = 0

What part(s) of the loop did it just do?

Do the assignment in the body of the loop one more time:

(gdb) next
1: sum = 0

Again, sum does not change. Aha! We think we know what
is causing the error.

Changing variables while program is running:

What we can do now is correct the value of sum and see if
the rest of the program doesn't mess it up. Let's give the
sum variable the value it should have:

(gdb) set variable sum = 100

(i.e., 10+20+30+40).

And, we'll let the program continue to run:

(gdb) continue
Continuing.
The average is: 25
Thank you for using the averager!
Program exited normally.

You can see that we get the correct average, based on the value we
just gave sum. So, the error in sumNumbers()
is probably the only place needing to be fixed.

Fix the problem, recompile, and see if the program runs properly now.

Getting help in Gdb:

Note that the Gdb commands we've learned (plus others) are described by
the Gdb help command. Use: