Skip to content

Latest commit

 

History

History
132 lines (88 loc) · 5.67 KB

day1.rst

File metadata and controls

132 lines (88 loc) · 5.67 KB

Day 1: Introduction

:download:`Lecture slides <slides/day1.pdf>`

Using GDB

The GNU Debugger, or GDB, is a freely available tool that you will find almost everywhere. Using a debugger, you will be able to stop execution of your program, step through execution, and observe the state of your program. You can also do post-mortem analysis on core dump files, which are left by the operating system when your program suffers a catastrophic crash.

We will use this :download:`program <code/day1/quicksort.c>` for learning gdb:

.. literalinclude:: code/day1/quicksort.c
    :language: c

To invoke gdb, type:

$ gcc -g -o quicksort quicksort.c
$ gdb quicksort

You should investigate the following commands in gdb, and understand how and when they should be applied. Commands generally lie in two categories: controlling execution and inspecting the state of the program. First though, is the list command:

  • list: List source code. You can list a particular function by using "list function-name". This is useful when using the GDB interface from the command line.

Controlling execution

Breakpoints

A breakpoint is a place in the code where GDB will stop execution. The most simple type of breakpoint unconditionally stops the program every time that point is reached during execution. There are other kinds of breakpoints, such as conditional breakpoints and temporary breakpoints, that we will not cover here.

Running

  • run: Run your program from the beginning. This will run the program until completion, the next breakpoint, or until some error occurs.
  • continue: Continue execution until completion, the next breakpoint, or until some error occurs.
  • step: Execute the next line of code, including entering functions.
  • next: Execute the next line of code, but skip over function calls.

Inspecting state

When a function is called in a program, it pushes down the current program address, function parameters, and local variables for the function on a function call stack. Each entry on this stack is called a stack frame. The stack serves as a space to allocate temporary variables and let the program know how to return from the function. Among other things, the stack can tell us how the program got to its current state when it crosses a breakpoint or crashes.

Stack

  • backtrace: Print the stack trace, from the current function down to the main() function (in C).
  • up and down: Go up and down in the function call stack to examine function parameters and local variables.

Memory

  • print: Print the current state of a given variable or expression. The print command is smart enough to print arrays and structs properly. You can even make function calls as part of the expression.
  • display: Like print, but this produces output every time the program stops. This prints nothing if the expression is not valid.

To see the contents of the array, you will have to cast the pointer as an array so that GDB can display it correctly:

display (int[SIZE])*array

Using Gprof

Compile the program with -pg:

$ gcc -pg -O3 -o pgm pgm.c

When you run the program, a gmon.out file will be created. Then, we run gprof to obtain text output:

$ gprof pgm gmon.out

We will use this program to trying gprof:

.. literalinclude:: code/day1/find-primes1.c
    :language: c

You can download all the variations using these links: :download:`primes.zip <code/day1/primes.zip>`

Makefiles

make makes it easy to compile large code bases. A Makefile lets us specify what needs to be compiled and what are the dependencies.

An example of a simple Makefile is below:

.. literalinclude:: code/day1/Makefile
    :language: make

In the :download:`make directory <code/day1/make.zip>` for today’s lab, there are eight files comprising a hypothetical program. Don’t try to figure out what the program does, as it doesn’t do anything interesting. Instead, write a Makefile for the whole program that separately compiles each .c file and generates a single executable file. Then add a target clean to the Makefile that removes executable and object files, and then add another target main.tgz that creates a tarfile with that name containing all header and source files. The command:

$ tar -czvf <tarfilename> <listoffiles>

will create a compressed tar file containing those files.