Lab 2 - Using the Debugger


In this lab, we cover how to use the debugger with a sample program. You will need to fix numerous errors in the program using GDB and Valgrind.

Lab Materials


Assignment


The sample program currently produces a segmentation fault:
$ ./bugs
The current bug population of Earth is about: 1480000000000000000
The current bug population of Mars is about: 140727437236104
The current bug population of Venus is about: 0
The total bug population of the solar system is: 1480000000000000000
The most useless bug is a butterfly Segmentation fault (core dumped)
Your task for this lab is to find and fix all of the problems with the aid of debugger. When you are finished, the test output should print:
$ make test
gcc -g bugs.c -o bugs
valgrind --leak-check=full ./bugs > bugs_output.txt 2> valgrind_output.txt

=======================================
VALGRIND DIFF
---------------------------------------

=======================================
PROGRAM DIFF
---------------------------------------

$ cat bugs_output.txt
The current bug population of Earth is about: 1480000000000000000
The current bug population of Mars is about: 0
The current bug population of Venus is about: 0
The total bug population of the solar system is: 1480000000000000000
The most useless bug is a mosquito
The most colorful bug is a butterfly
The most colorful bug is a a is bug colorful most The
The current bug adjective is: (null)
Bugs didn't cause me to crash!

$ cat valgrind_output.txt
==#== Memcheck, a memory error detector
==#== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==#== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==#== Command: ./bugs
==#== 
==#==
==#== HEAP SUMMARY:
==#==     in use at exit: 0 bytes in 0 blocks
==#==   total heap usage: 7 allocs, 7 frees, 35 bytes allocated
==#== 
==#== All heap blocks were freed -- no leaks are possible
==#== 
==#== For counts of detected and suppressed errors, rerun with: -v
==#== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Lab Report


Once you have fixed the problems in the given program, prepare a report for this lab answering the following questions. Please make sure that your lab report is in pdf format.
  1. Explain the difference between a hardware breakpoint and a software breakpoint. [5 Points]
  2. Explain the difference between a breakpoint and a watchpoint. [5 Points]
  3. Is it possible to change the value of a variable during debug session? If so, mention the gdb command for doing it. [5 Points]
  4. Consider the following piece of code [5 Points]:
    #define STRING_LENGTH 256 /* Defined in some obscure header file and included in the source file */
    
    …
    
    int main (void)
    {
    	char	my_string[STRING_LENGTH] = “This world is a beautiful place!”;
    	
    	print (“%s\n”, my_string);
    	
    	return 0;
    }
    While debugging the program, you place a breakpoint inside the main function. Once the breakpoint is hit, Your job is to find out the length of the variable “my_string” (i.e. 256) while debugging. How can you do that? Remember that the macro will get pre-processed and you won’t be able to use:
    print STRING_LENGTH

  5. Consider the following loop [10 Points]:
    for (i = 0; i < 1000000; ++i) {
    	...
    	read_page (i);
    	...
    }
    During the execution of this loop, you get a segmentation fault for some value of ‘i’ let’s say i = 10000. You want to see what exactly happens inside the loop in that iteration. One way to do it is to place a breakpoint in the loop body, manually wait for it to get hit 9999 times and then begin your investigation in the 10000th iteration. This is certainly undesirable and there should be a better way to do it. Can you figure out an efficient method to resolve this problem?
  6. Consider the following code segment [10 Points]:
    void scheduler ( … )
    {
    	/* Get the priority of the highest priority ready task */
    	int priority = get_high_priority ( … );
    	
    	/* Fetch the actual task */
    	TASK* task = fetch_task (priority);
    	
    	/* Schedule the task */
    	run (task);
    }
    You want to store the priority value when a certain task-x is selected for running inside the scheduler. Can you figure out a way to do that using gdb? (hint: You may want to use 'conditional breakpoint' and 'convenience variables' to solve this problem)

Submission


The total grade for this lab will be awarded based on your submitted code [60%] and lab report [40%]. In order to submit your source code, use the the 'tar' target included in the lab's Makefile. Change the STUDENT_ID variable in the Makefile to your student ID and type:
make tar




< Back to the Lab Home Page