1. Goals for this week:
-
Practice compiling and running C programs:
gcc
and usingmake
. -
Practice with arrays in C.
-
Input in C: scanf for reading from stdin, and our read_file library to read from a file (used in the next Lab assignment).
-
Learn some basic
gdb
debugging commands. We won’t have time to learn all ofgdb
this week, but we’ll see some debugging features beyond usinggdb
as a calculator.
Start by creating a week02
in your cs31/weeklylab
subdirectory
and copying over some files:
cd ~/cs31/weeklylab
mkdir week02
cd week02
pwd
/home/you/cs31/weeklylab/week02
cp ~newhall/public/cs31/week02/* .
ls
arrays.c Makefile testprog.c types_scanf.c
2. C compiling and running
First, let’s remind ourselves of the basics of compiling and running C programs.
Now, let’s try it out on one of the files you copied over (we will use the -g
and -o outfile
options to gcc):
gcc -g -o testprog testprog.c
./testprog
With the code you copied over is a Makefile. In this file are rules for
compiling executables from the .c
source files that are executed by typing in
the make
command. make
is very convenient way to compile without having to
type in a long gcc
command every time, you just need to type make
:
make # this will compile all files as specified by the all: rule
make clean # this removes all files generated by make (they can be rebuilt)
3. Arrays
Together we are going to start by looking at arrays.c
, which contains
examples of how to use (and abuse) arrays in C.
4. Input in C
We are going to look at two examples of reading in input values into a C program.
-
The first example, in
types_scanf.c
, shows examples thescanf
function from the C stdio library to read in different type values from the users.Note that
scanf
needs to know the memory location of where to put the values read in, and we use the&
operator on a variable name to pass this location toscanf
. For the Lab 2 assignment you will need to do something similar when you call library functions to read in values from a file. We’ll talk much more about what that ampersand means as we build up our C programming skills in future assignments. -
The second example, in
testfile.c
, shows some examples of reading in values from a file using the C read_file library that the CS31 instrctors wrote (implemented inread_file.c and read_file.h
. + Information about using the library is documented in comments in the.h
file. Let’s open that in one window, and opentestfile.c
program in another:vim read_file.h vim testfile.c
testfile.c
has some code to open an input file, given as a command line argument when run, and to read in an int value. It is run like this:./testfile <inputfile> # specify the name of an inputfile on the command line # examples: ./testfile values1 # run testfile with values1 as its inputfile ./testfile values2 # run testfile with values2 as its inputfile
Looking at the contents/format of the
values1
andvalues2
files:cat values1 cat values2
and refering to the library interface commented in
readfile.h
, add calls to readfile library functions to thetestfile.c
program to read in the next few values from an input file. Then compile and try running.vim testfile.c make ./testfile values1 ./testfile values2
5. GDB intro
gdb
is the gnu debugger for C and C++ programs. Last week we used gdb
as a
calculator and converter, but it is normally used to help debug programs. Over
the course of the semester will will use gdb
and learn more and more
features. Today, we will learn just a few basics.
To use the debugger, you usually want to compile your C program with the -g
flag to add debugging information to the a.out
file (this allows gdb
to map
binary machine code to C program code that the programmer understands).
$ gcc -g -o testprog testprog.c
The makefile already has this rule for us, so let’s just run make
.
Next, we will run the executable file inside the gdb debugger:
$ gdb ./testprog
The first thing we get is the gdb prompt (our program has not yet started). Typically we will set a break point at main. A breakpoint tells gdb to grab control at a certain point in the execution, in this case right before the first instruction in main is executed:
(gdb) break main
Breakpoint 1 at 0x652: file testprog.c, line 16.
Next, we will enter the run command at the gdb prompt to tell gdb to start running our program:
(gdb) run
The run command will start your program running, and gdb will only gain control again when a breakpoint is hit.
There are a few other main gdb commands we will learn today, the first is
the list
command that lists the C source code around the point where we
are in the execution:
(gdb) list
list
with a line number lists the source code around that line:
(gdb) list 30
The next
(or just n
for next), which tells gdb to execute the next
instruction and then grab control again:
(gdb) next # this will execute the instruction x = 10
The print
command can be used to print out a value of a program
variable or expression:
(gdb) print x
$1 = 10
cont
tells gdb to let the program continue running. Since we have no more
breakpoints it will run until termination.
(gdb) cont
Continuing.
x = 10 y = 8 z = 0.00
x = 10 y = 8 z = 53.00
[Inferior 1 (process NUM) exited normally]
(gdb)
Now lets add a breakpoint in the function mystery
, and rerun the program:
(gdb) break mystery
Breakpoint 2 at 0x5555555546d5: file testprog.c, line 32.
The run
command starts the program’s execution over from the beginning.
When re-run, the breakpoint at the beginning of the main
function will be
hit first (list
will display the code around the breakpoint).
(gdb) run
Breakpoint 1, main () at testprog.c:16
16 x = 10;
(gdb) list
Lets set a breakpoint at line 20, right before the call to mystery, then type
cont
to continue execution from breakpoint in main:
(gdb) break 20
Breakpoint 3 at 0x55555555468e: file testprog.c, line 20.
(gdb) cont
When the program next reaches the breakpoint we just set at line 20 (Breakpoint 3). We could print out the argument values before the call, then type cont, to continue the program’s execution:
Continuing.
x = 10 y = 8 z = 0.00
Breakpoint 3, main () at testprog.c:20
20 z = mystery(x, y);
(gdb) print x
(gdb) print y
(gdb) cont
After continuing the breakpoint in mystery
is hit next (Breakpoint 2),
let’s step through
some of the mystery function’s execution, and print out some of its
parameters and locals.
We can use the print
command to print out expressions in the program, so
let’s print out the values of the arguments passed to mystery, and type cont
to run until the next break point is hit:
(gdb) print a # print out the value of the variable a
(gdb) print (a - 4) # print out the value of the expression (a - 4)
(gdb) list
The where
or bt
command list the call stack:
(gdb) where
When you’re done using gdb
, type the command quit
.
(gdb) quit
$
If you use gdb to help you debug the lab this week, you will need to give
the run
command a commandline argument that is the file name:
(gdb) break main
(gdb) run floats.txt
In general, for programs with command line arguments,
simply list the arguments after the run
command, for example
to run with 3 command line arguments, 6, 4, and hello, do the
following:
(gdb) break main
(gdb) run 6 4 hello
We will talk more about C and gdb over the course of the semester.
6. Lab 2 Intro
Lets talk through the next Lab Assignment, where you will implement a C program that, among other things, performs a sorting task.