II. ANTECEDENTES DEL ÁREA DE INFLUENCIA DEL PROYECTO
2.1. Municipio de Uriondo
2.1.3. Componente socio-cultural 1.Características socio-culturales
1 #include <unistd.h> 2
3 int main(int argc, char *argv[]) 4 { 5 int i = 0; 6 7 while(i < 100) { 8 usleep(3000); 9 } 10 11 return 0; 12 }
Compile this like normal and then start it under gdb like this: gdb ./ex31
Once it’s running I want you to play around with these gdb commands to see what they do and how to use them. help COMMAND Get a short help with COMMAND.
break file.c:(line|function) Sets a break point where you want to pause execution. You can give lines or func- tion names to break at after the file.
run ARGS Runs the program, using the ARGS as arguments to the program. cont Continues execution until a new breakpoint or error.
step Step through the code, but move into functions. Use this to trace into a function and see what it’s doing. next Just like step, but go over functions by just running them.
backtrace (or bt) Does a "backtrace", which dumps the trace of function calls leading to the current point in the program. Very useful for figuring out how you got there, since it also prints the parameters that were passed to each function. It’s also similar to what Valgrind reports when you have a memory error.
set var X = Y Set variable X equal to Y.
print X Prints out the value of X, and you can usually use C syntax to access the values of pointers and contents of structs.
ENTER The ENTER key just repeats the last command. quit Exits gdb
Those are the majority of commands I use with gdb. Your job is to now play with these and ex31 so you can get familiar with the output.
Once you’re familiar with gdb you’ll want to play with it some more. Try using it on more complicated programs like devpkg to see if you can alter the program’s execution or analyze what it’s doing.
32.4
Process Attaching
The most useful thing about gdb is the ability to attach to a running program and debug it right there. When you have a crashing server or a GUI program, you can’t usually start it under gdb like you just did. Instead, you have to start it, hope it doesn’t crash right away, then attach to it and set a breakpoint. In this part of the exercise I’ll show you how to do that.
After you exit gdb I want you to restart ex31 if you stopped it, and then start another Terminal window so you can process attach to it. Process attaching is where you tell gdb to connect to a program that’s already running so you can inspect it live. It stops the program and then you can walk through it, and when you’re done it’ll continue just like normal.
184 CHAPTER 32. EXERCISE 31: DEBUGGING CODE
Here’s a session of me doing it to ex31, stepping through it, then fixing the while-loop to make it exit.
ex31.sh-session
1 $ ps ax | grep ex31 2 10026 s000 S+ 0:00.11 ./ex31 3 10036 s001 R+ 0:00.00 grep ex31 4 5 $ gdb ./ex31 100266 GNU gdb 6.3.50-20050815 (Apple version gdb-1705) (Fri Jul 1 10:50:06 UTC 2011) 7 Copyright 2004 Free Software Foundation, Inc.
8 GDB is free software, covered by the GNU General Public License, and you are 9 welcome to change it and/or distribute copies of it under certain conditions. 10 Type "show copying" to see the conditions.
11 There is absolutely no warranty for GDB. Type "show warranty" for details.
12 This GDB was configured as "x86_64-apple-darwin"...Reading symbols for shared libraries .. done 13
14 /Users/zedshaw/projects/books/learn-c-the-hard-way/code/10026: No such file or directory
15 Attaching to program: `/Users/zedshaw/projects/books/learn-c-the-hard-way/code/ex31', process 10026. 16 Reading symbols for shared libraries + done
17 Reading symbols for shared libraries ++... done 18 Reading symbols for shared libraries + done
19 0x00007fff862c9e42 in __semwait_signal () 20
21 (gdb) break 8
22 Breakpoint 1 at 0x107babf14: file ex31.c, line 8. 23
24 (gdb) break ex31.c:11
25 Breakpoint 2 at 0x107babf1c: file ex31.c, line 12. 26
27 (gdb) cont 28 Continuing. 29
30 Breakpoint 1, main (argc=1, argv=0x7fff677aabd8) at ex31.c:8 31 8 while(i < 100) { 32 33 (gdb) p i 34 $1 = 0 35 36 (gdb) cont 37 Continuing. 38
39 Breakpoint 1, main (argc=1, argv=0x7fff677aabd8) at ex31.c:8 40 8 while(i < 100) { 41 42 (gdb) p i 43 $2 = 0 44 45 (gdb) list 46 3
47 4 int main(int argc, char *argv[]) 48 5 { 49 6 int i = 0; 50 7 51 8 while(i < 100) { 52 9 usleep(3000); 53 10 }
32.4. PROCESS ATTACHING 185 54 11 55 12 return 0; 56 57 (gdb) set var i = 200 58 59 (gdb) p i 60 $3 = 200 61 62 (gdb) next 63
64 Breakpoint 2, main (argc=1, argv=0x7fff677aabd8) at ex31.c:12
65 12 return 0;
66
67 (gdb) cont 68 Continuing. 69
70 Program exited normally. 71 (gdb) quit
72 $
Note 12 OSX Problems
On OSX you may see a GUI prompt for the root password, and even after you give it you still get an error from gdb saying "Unable to access task for process-id XXX: (os/kern) failure." In that case stop both gdb and the ex31 program, then start over and it should work as long as you successfully entered the root password.
I’ll walk through this session and explain what I did:
gdb:1 I use ps to find out what the process id is of the ex31 I want to attach.
gdb:5 I’m attaching using gdb ./ex31 PID replacing PID with the process id I have.
gdb:6-19 gdb prints out a bunch of information about it’s license and then all the things it’s reading.1
gdb:21 The program is attached and stopped at this point, so now I set a breakpoint at line 8 in the file with break. I’m assuming that I’m already in the file I want to break when I do this.
gdb:24 A better way to do a break, is give file.c:line format so you can be sure you did the right location. I do that in this break.
gdb:27 I use cont to continue processing until I hit a breakpoint.
gdb:30-31 The breakpoint is reached so gdb prints out variables I need to know about (argc and argv) and where it’s stopped, then the line of code for the breakpoint.
gdb:33-34 I use the abbreviation for print "p" to print out the value of the i variable. It’s 0. gdb:36 Continue again to see if i changes.
gdb:42 Print out i again, and nope it’s not changing.
gdb:45-55 Use list to see what the code is, and then I realize it’s not exiting because I’m not incrementing i. gdb:57 Confirm my hypothesis that i needs to change by using the set command to change it to be i = 200.
This is one of the best features of gdb as it lets you "fix" a program really quick to see if you’re right. gdb:59 Print out i just to make sure it changed.
gdb:62 Use next to move to the next piece of code, and I see that the breakpoint at ex31.c:12 is hit, so that means the while-loop exited. My hypothesis is correct, I need to make i change.
186 CHAPTER 32. EXERCISE 31: DEBUGGING CODE
gdb:67 Use cont to continue and the program exits like normal. gdb:71 I finally use quit to get out of gdb.