cd cs31/weeklylab pwd mkdir week05 ls cd week05 pwd cp -r ~newhall/public/cs31/week05/* . ls Makefile gdb_examples/ memparts.c pointers.c valgrind_examples/
$ cat pointers.c int pointers() { int x, y, *ptr; x = 8; ptr = &y; *ptr = 30; x = *ptr + 20; }Lets compile a simple program using pointers and see what its assembly code looks like (or just type make):
$ gcc-4.4 -m32 -S pointers.cLet's cat out the .s file an look at some of the instructions. The thing to note is that when the *ptr is used (ptr is dereferenced), first the value of the ptr variable is obtained (its value is the address of y) and then the value at that address is accessed: a level of indirection.
Here is the code with some annotations around what it is doing (note the use of leal instruction):
$ cat pointers.s pointers: pushl %ebp movl %esp, %ebp subl $16, %esp movl $8, -4(%ebp) # x = 8 leal -8(%ebp), %eax # R[%eax] <--- &(M[R[%ebp]-8]]): R[%eax] <-- &y movl %eax, -12(%ebp) # ptr = &y; movl -12(%ebp), %eax # R[%eax] <-- ptr: R[%eax] <-- &y movl $30, (%eax) # what ptr points to gets 30 movl -12(%ebp), %eax movl (%eax), %eax addl $20, %eax movl %eax, -4(%ebp) leave ret
Let's just run this and see where some things are:
./mempartsThe thing to note now is that heap memory locations (malloc'ed space) and local variable locations (on the stack) are at very different addresses. We will revisit this program later in the semester when we talk about other parts of program memory.
cd into the gdb_examples subdirectory.
First, run make to build the executables (note they are all compiled with -g).
Let's look through a couple of the example programs in gdb, following along in my GDB Guide.
We are going to look at badprog and segfaulter in gdb. These are listed in the "Sample gdb sessions" part of my gdb guide under run 1: debugging badprog and run 2: debugging segfaulter.
Up the page on this guide are lists of common gdb commands and some examples
of how to use them.
Valgrind is a tool for finding heap memory access errors and memory leaks in C and C++ programs. Memory access errors are often very difficult bugs to find, and valgrind helps you easily find errors like reads or writes beyond the bounds of a malloc'ed array, accessing free'ed memory, reading uninitialized memory, and memory leaks (not freeing malloc'ed space before all variables referring to it go out of scope).
To use valgrind, just compile with -g, and run valgrind on your program:
make valgrind ./badprogThe output at first seems a bit cryptic, but once you see the basics of how to interpret it, it is extremely helpful for finding and fixing memory access errors. Let's look at my Valgrind Guide to see how to interpret some of this valgrind output. This guide contains links to other valgrind resources, and the README file in the code you copied over lists some command line options for running valgrind.