lab07 : Practicing with development Tools: gdb and valgrind
num | ready? | description | assigned | due |
---|---|---|---|---|
lab07 | true | Practicing with development Tools: gdb and valgrind | Wed 02/24 12:00AM | Thu 03/04 11:59PM |
Goals
Learning objectives. At the end of this lab, students should be able to:
- Use gdb to examine and fix buggy C++ code
- Use valgrind to check for memory leaks and explore memory use
Modality
Per the modality announced, you may work on this lab in pairs, but really you each should consider this opportunity to learn gdb and valgrind. This lab would work best with you each in parallel trying things out and talking. You each really will want the opportunity to experience and practice with these tools. Regardless, each person must fill out their own gradescope form. Again, per the prior announcements on modality, you may only work with the same person twice.
Orientation
Even the most experienced programmers introduce bugs into their code, especially as the complexity of the code and data management for a larger system expand. Most software development companies have many in house tools to help their developers. In addition, there are several open source general tools that are useful to have experience with. The primary goal of this lab is to expose you to these tools. You will need to continue to practice with these tools throughout your computing career to truly learn them.
The tools we will play with this week include gnu’s debugger gdb and valgrind. These tools have different uses. You are expected to understand some basics about all of them by doing some reading on your own.
1) gdb is a debugger allowing you to examine the state of your program during execution (or at the moment it crashes): https://www.gnu.org/software/gdb/ “GDB can do four main kinds of things (plus other things in support of these) to help you catch bugs in the act:
Start your program, specifying anything that might affect its behavior.<br>
Make your program stop on specified conditions.<br>
Examine what has happened, when your program has stopped.<br>
Change things in your program, so you can experiment with correcting the effects of one bug and go on to learn about another. <br>
Those programs might be executing on the same machine as GDB (native), on another machine (remote), or on a simulator. GDB can run on most popular UNIX and Microsoft Windows variants, as well as on Mac OS X."
A useful reference about gdb that we recommend you read: https://ucsb-cs32.github.io/topics/tools_gdb/
2) valgrind is a software analysis tool to detect memory management (and threading bugs) and profile your code. https://valgrind.org/
Step by Step
Step 1: gdb
The GNU debugger (a.k.a. gdb) is a very powerful tool for analyzing what your program is doing at run-time.
There is a useful tutorial at the general CS32 course website (https://ucsb-cs32.github.io). Referring to this tutorial will directly help you respond to the first 4 questions for this lab.
In general to have the output of gdb be useful, you will need to compile with the -g
option. Add -g
to the CXXFLAGS
in your Makefile
.
The order of flags on the CXXFLAGS
line does not matter. You can add it to the end or the beginning.
CXXFLAGS = -g -std=c++11 -Wall -Wextra -Wno-unused-parameter -Wno-unused-private-field
Every time you change your Makefile
you should always do a make clean
first. Rebuild your tests.
Before moving on, may want to just experiment with each of the following gdb commands:
help
break
display
print
next
step
backtrace
watch
There are examples for these commands on the gdb entry on this (https://ucsb-cs32.github.io) page. Since you might not always know what you are looking for when debugging, experimentation is very important.
Step 2: Debugging someone else’s code
It’s time to put your new skills to the test. You will be given an executable file, but not all the source code.
It is possible that you may have a program that calls a library and you won’t be given all the source code to the library or the library was built without the -g option. Here we are reversing this a little bit. You are given some code, but the code to the main function is not given to you. You will not be able to step through all of the code. In a sense, you can treat main function like a ‘black box’, which calls the code you are given. You don’t need to know what the main function is doing, but you will have to answer a few questions about how it calls the code you are given.
Download the 4 files from here:
- http://cs.ucsb.edu/~richert/cs32/misc/lab07/
Or copy from here:
- /cs/faculty/richert/public_html/cs32/misc/lab07/*
Guidelines for Answering
Use the associated gradescope online tool to answer questions for this lab. Note that this lab is about giving you experience with these tools. ‘Cheating’ really only cheats you of the opportunity to learn.
https://www.gradescope.com/courses/222015/assignments/1060116
Question 1
Start up gdb
and load in segProgram
.
gdb ./segProgram
Now run the program with the run
command followed by your umail address:
(gdb) run cgaucho@umail.ucsb.edu
It will stop as soon as it encounters the segfault. Note that when you use the command run [args]
, it takes [args]
as the command line argument (i.e. the value of argv[1]
). This is a necessary step in order to produce the answer Gradescope is expecting.
- q1a: What index of the array is the program trying to access? Write your answer in
q1 'free response'
. - q1b: What value is the program trying to store in the array when the fault occurred? Write your answer in file
q1 'free response'
Question 2
For the remainder of the questions use the debugProgram executable.
gdb ./debugProgram
Remember to pass in your umail address when running through gdb in order to obtain the correct values.
(gdb) run cgaucho@umail.ucsb.edu
q2: What is the value of the string ‘a’ when debugFunction1 is called?
Hint: use the break
feature to stop the program
Question 3
q3: What is the value of the string ‘a’ when debugFunction1 is called a second time?
Question 4
q4: How many recursive calls to recursiveFunction are in the backtrace (also called a stack trace) when variable a == 100
in recursiveFunction
? Put your answer in q4
.
Hints:
- Use
backtrace
(abbreviatedbt
), along with conditional breakpoints:break
someplaceif
condition - What is the number of stack frames when the last instance of recursiveFunction is created? You may need to page through them.
- Then think about how many of those stack frames are actually for the recursive function, as opposed to other functions that have been put on stack before or after.
Step 3: Debugging and fixing given code (further gdb exploration)
Now grab the next set of files: https://github.com/ucsb-cs32-w21/lab07-STARTER
or on csil:
cp ~zjwood/32Public/lab07GDB.zip .
For the code in lab07GDB compile the code and you will be executing the following commands (Q denotes a question to answer on the corresponding gradescope assignment):
% gdb example
...
(gdb) b example.cpp:33
(gdb) r
(gdb) print exp
*Q5* (gdb) print *exp
(gdb) print exp->c
(gdb) print exp->other
(gdb) print *exp->other
*Q6* (gdb) print exp->other->a
(gdb) c
(gdb) list
(gdb) back
(gdb) quit
Question 5
Fill in the blank with what is printed here:
(gdb) print *exp
Question 6
Fill in the blank with what is printed here:
(gdb) print exp->other->a
Question 7
Explain in your own words what is happening for this line of code:
(gdb) print exp->other->a
submit fixed file
Now look at the code and fix it so that when it compiles and runs it works - i.e. it does not segfault and will ouput a number. NO NOT EDIT main at ALL. Consider the simpliest fix so that the code does not crash - this means being clear on why it is crashing. This task should be accomplished by adding one line of code and modifying one other. The ideal solution will preserve all functions, including parameter types and calls. Think of this as an oportunity to practice with understanding pointers and memory allocation/management (as those are topics that often lead to seg faults). Submit the fixed code for autograding at the lab07Lab gradescope assignment.
Turn inyour fixed code here: https://www.gradescope.com/courses/222015/assignments/1066844
Step 3: valgrind
Once you feel comfortable with debugging, another useful tool is valgrind. Consider reading the quickstart guide here: https://www.valgrind.org/docs/manual/QuickStart.html
valgrind task 1
Starting with the provided versions of lecture code, from: https://github.com/ucsb-cs32-w21/lab07-STARTER or
cp ~zjwood/32Public/testValgrindBase.zip
Compile the versions of the code in both version1 and version2 and run valgrind and copy their report into the gradescope worksheet.
valgrind --leak-check=full version1/a.out 300 300 out.ppm valgrind --leak-check=full version2/a.out 300 300 out.ppm
Question 8
Copy the valgrind reports to the gradescope assignment.
valgrind task 2
Next, fix the code. Make a copy of the version2 code - you must leave the data as raw pointers (do not swap them to smart pointers) and fix the code so that no memory is left on the heap. Note that it will be fairly straight forward to address many of the issues, however, one issue will require making sure that the correct destructor is used for each of the shapes.
You will need to turn in your working solution and expect that valgrind will be run on your solution to confirm your solution.
https://www.gradescope.com/courses/222015/assignments/1060111
valgrind task 3
Valgrind is also useful for measuring overall memory use. This is a fun topic to explore in depth, but for today, lets just consider one variable which is function parameters. Make a version4 of the code and change the loops in main to generate 1000 shapes total (to do this just change each loop to add 500 each of rectangles and ellipses for a total shapes of 1003 is fine with the three triangles). Use valgrind and report the total memory use (on the gradescope worksheet). Now, change the function parameter passed to writeOut to be a reference and re-run valgrind. Report the memory use and reflect briefly on why there is a change in the overall memory use.
Question 9
Copy the valgrind reports and your reflections to the gradescope assignment.
——
Grade:
gradescope worksheet (9 questions):
https://www.gradescope.com/courses/222015/assignments/1060116
gradescope autograder (2 autograder tests - fixed seg fault and fixed memory leak):
https://www.gradescope.com/courses/222015/assignments/1066844
https://www.gradescope.com/courses/222015/assignments/1060111
<p>
——
Acknowledgements:
Some of this lab is from R. Wang, some from A. Keen, some from me (Z. Wood)