TWiki
>
CS361fall13 Web
>
Homework6
(2013-10-17, Main.tmerri4)
(raw view)
E
dit
A
ttach
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css' /> <link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css' /> <script src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js" type="text/javascript"></script> <script src="http://alexgorbatchev.com/pub/sh/current/scripts/shAutoloader.js" type="text/javascript"></script> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/XRegExp.js' type='text/javascript'></script> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'></script> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shAutoloader.js' type='text/javascript'></script> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'></script> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js' type='text/javascript'></script> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCss.js' type='text/javascript'></script> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js' type='text/javascript'></script> <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushBash.js' type='text/javascript'></script> <script type="text/javascript"> SyntaxHighlighter.all() </script> ---+ Homework 6 - Build your own debugger In this homework we'll be building a stripped down version of gdb. The template solution comes with a library for reading debugging symbols (dwarf_symbol_reader) and for processing user input (debugger_interface), allowing you to focus on developing the features. ---+++ Initial Setup You'll need a few libraries first. Run the following command before trying to compile the template... <pre name="code" class='brush: bash'> sudo apt-get install libelf-dev libdwarf-dev dwarfdump libncurses5-dev </pre> dwarfdump is a program that displays the dwarf debugging symbols for a program. It may be helpful to you for this assignment. ---++ API Info You'll have to use the ptrace API for this assignment along with a couple of libraries that I wrote. Familiarize yourself with these things *BEFORE* starting the assignment! I suggest you peek at the .c and .h files also, just to get a flavor of what is going on. ---+++ Debugger Interface (debugger_interface.h) This module handles the user input to the debugger. Each command from the user has a command type and a value associated with it. For instance, if the user types "b 7" then the command type is CMD_TYPE_BREAKPOINT and the value is the line number where we want to set the breakpoint. Values can be strings (for instance the name of a variable for printing) or integers so we use a union type to represent it. The union type in the user_command struct is called value. Below is an example of how to access the line_number from a user_command. <pre name="code" class='brush: cpp'> user_command * cmd = debugger_interface_get_cmd(); //now handle the input switch(cmd->command_type){ case CMD_TYPE_BREAKPOINT: set_breakpoint_from_line_number(cmd->value.line_number); break; case CMD_TYPE_PRINT: printf("printing not implemented yet\n"); break; case CMD_TYPE_CONTINUE: //tell the child to keep going break; } </pre> ---+++ dwarf_symbol_reader.h This module allows you to get info about the program that you are debugging (assuming that program was compiled with dwarf debugging symbols). This includes such info as function names, function starting and ending addresses, variable names and locations, etc... The dwarf_symbol_reader.h file has lots of comments so make sure to take a look in there. *For all of the parts of the assignment you will need to utilize this library!*. Dwarf considers each object file a "compilation unit". For this assignment we'll only have a single compilation unit because the programs we will be using are very simple. Many of the functions in dwarf_symbol_reader.h take a compilation unit, so you'll want to grab the compilation unit at the beginning of the debugging process using the function *dwarf_get_compilation_unit*. A *die* (debugging information entries) contains the debugging information for a given entity in a program. So a function would have a die, a variable would have a die, and so forth. In fact, the whole compilation unit also has a die and is available in the *struct dwarf_compilation_unit* type as *root_die*. The dies are organized into a tree with the compilation unit as a root. So, if variable x is in function fun1, then x's die is a child of fun1 . Most of the functions in dwarf_symbol_reader.h take a die as a parameter. One of the main things that you can do with these functions is iterate through a bunch of dies. So lets say you wanted to loop through all the function dies in your program. You would do the following <pre name="code" class="brush: cpp;"> //start with the first child of the root die Dwarf_Die func_die = dwarf_get_next_function(compilation_unit->root_die, compilation_unit); while(func_die){ //do something with the function die //... //now get the next one func_die = dwarf_get_next_function(func_die, compilation_unit); } </pre> There are similar iterator functions available for variables. ---+++ Using Ptrace The Ptrace library allows a debugging program to have total control over the debuggee. Using Ptrace, our debugger (via the operating system) can modify a program's instructions, read a program's memory, stop it, start it, single step it, etc... The man page for Ptrace is great and is linked below in the references. *You will need to make at least 1 Ptrace call for every part of this homework*. ---+++ a. Setting a breakpoint The first thing you will need to do is set a breakpoint and have the program stop at that line. To do this you will have to modify the right instruction by replacing the low order byte with an int3 (0xCC) op code. Make sure to store away the old instruction so that you can put it back once the breakpoint has been hit. The users interaction with this functionality should look like this... <pre name="code" class='brush: bash'> 361db>> b 7 breakpoint 1 set at line 7 361db>> c continuing... breakpoint 1 hit 361db>> </pre> ---+++ b. Where am I? When debugging it is always helpful to know where you are in a certain file. For part 1 you will print out the line you are currently on and the file name. (HINT: use the instruction pointer from ptrace to figure out the line). Here is the intended output... <pre name="code" class='brush: bash'> 361db>> where line 1 in prog1.c </pre> ---+++ c. Persistent breakpoints When you hit a breakpoint you must take the original instruction and put it back, thus removing your breakpoint. For part b we now make our breakpoints persistent so that they stick around. (Hint: take a look at single stepping with ptrace). The user should be able to hit the same breakpoint multiple times without having to set it more than once. ---+++ d. Multiple breakpoints Its not very fun for the user to only be able to set one breakpoint at a time. Now allow the user to have multiple breakpoints set concurrently. Here's an example of the expected output. <pre name="code" class='brush: bash'> 361db>> b 7 breakpoint 1 set at line 7 361db>> b 8 breakpoint 2 set at line 8 361db>>c hit breakpoint 1 361db>>c hit breakpoint 2 </pre> ---+++ e. Printing Variables Being able to inspect the value of a variable is an important part of debugging. For part e we will now implement the printing of variables. The p command will take two arguments: the first is the format specifier (/d for integer in decimal, /c for character, etc...) and the second is the variable name. *I will only test that your program can print integers and characters*. Here's the expected output. <pre name="code" class='brush: bash'> 361db>> b 7 breakpoint 1 set at line 7 361db>> p /d x 101 361db>> c </pre> ---+++ f. Printing out strings (15 % bonus) If you can print out a single value it should be too hard to also print out a string of characters. Modify your program to do just that. <pre name="code" class='brush: bash'> 361db>> p /s trueStr "CS 361 is so much fun!" 361db>> c </pre> ---+++ i. (WEEK 2) Printing out the stack trace (15% Bonus) This one should be fun. Now allow the users to see a simple stack trace after typing "bt". This should work for any number of function calls, including recursive ones. You will print the source file, line number and the input parameters. You can just assume that all input parameters are integers. Here's the output we should see given the following debuggee program... <pre name="code" class="brush: cpp;"> void h(int y){ printf("hello there: %d", y); } void g(int x){ h(x); } int main(){ g(10); } </pre> <pre name="code" class='brush: bash'> 361db>> b 2 breakpoint 0 set at line 2 361db>> c hit breakpoint 0 361db>> bt #0 h(y=10) at tests/prog5.c:2 #1 g(x=10) at tests/prog5.c:6 #2 main() at tests/prog5.c:10 </pre> ---+++ References 1.) Take a look at this blog entry...it should take you a long way <a href="http://www.alexonlinux.com/how-debugger-works">How a Debugger Works</a> 2.) <a href="http://linux.die.net/man/2/ptrace">The Ptrace man page</a> 3.) An in depth look into dwarf <a href="http://www.ibm.com/developerworks/opensource/library/os-debugging/index.html?ca=drs-">Debugging formats DWARF and STAB</a> 4.) <a href="http://www2.cs.uic.edu/~jakob/cs385s12/HW8addendum/">Walk-through of the template code</a> 5.) <a href="http://www2.cs.uic.edu/~jakob/cs385s12/DebuggingLecture/">Debugging Lecture</a>
E
dit
|
A
ttach
|
P
rint version
|
H
istory
: r4
<
r3
<
r2
<
r1
|
B
acklinks
|
V
iew topic
|
Ra
w
edit
|
M
ore topic actions
Topic revision: r4 - 2013-10-17 - 15:37:30 - Main.tmerri4
CS361fall13
Syllabus
Homework Schedule
Lecture Notes
Reading List
Additional Material
Piazza Board
EC2 Sign-In Page
ABOUT US
Our Department
Recent News
Contact Us
ACADEMICS
Prospective Students
Undergraduate
CS Minor
Graduate
Courses
RESEARCH
Overview
By Faculty
Labs
PEOPLE
Faculty
Adjuncts
Staff
Students
Alumni
Copyright 2016 The Board of Trustees
of the University of Illinois.
webmaster@cs.uic.edu
WISEST
Helping Women Faculty Advance
Funded by NSF