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:

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:

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:

Or copy from here:

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.

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:

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)