# 2014 February 3 # # Using GDB (debugger) on second variation of reverse program (reverse2.c) # # Added comments are preceded by a single # and a space. Lines starting # with # followed immediately by a number and no space are output from GDB. # # # Compile with the -g option to fully utilize the debugger. # Use GDB on the executable. # $ gcc -Wall -g -o reverse reverse2.c $ gdb reverse GNU gdb (GDB) Fedora 7.6.1-46.fc19 Copyright (C) 2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-redhat-linux-gnu". For bug reporting instructions, please see: ... Reading symbols from /homes/campbl4/GDB_Demo/reverse...done. # # Use the break command to set a breakpoint when the reverse function is called. # (gdb) break reverse Breakpoint 1 at 0x4006ec: file reverse2.c, line 15. # # The run command begins execution of the program. # (gdb) run Starting program: /homes/campbl4/GDB_Demo/reverse Please enter a string: hello Breakpoint 1, reverse (s=0x7fffffffe2d0 "hello\n") at reverse2.c:15 15 char * result = NULL; /* the reversed string */ Missing separate debuginfos, use: debuginfo-install glibc-2.17-20.fc19.x86_64 # # The backtrace (bt) command traces the stack of function calls. # (gdb) backtrace #0 reverse (s=0x7fffffffe2d0 "hello\n") at reverse2.c:15 #1 0x00000000004007d1 in main () at reverse2.c:48 # # The list command lists the source code if the executable was compiled with -g # Currently the listing is centered around the first executable statement in the # reverse function (where the breakpoint was set). # (gdb) list 10 #include 11 12 /* Return a new string with the contents of s backwards */ 13 char * reverse(char * s) { 14 15 char * result = NULL; /* the reversed string */ 16 int L, R; 17 char ch; 18 19 /* allocate enough memory to hold the copied string */ # # s is in the parameter list of the function reverse, so it is visible within this scope # Use the print command to see its value # (gdb) print s $1 = 0x7fffffffe2d0 "hello\n" # # result is a local variable of the function reverse, so it is visible within this scope # Use the print command to see its value (NULL) # (gdb) print result $2 = 0x0 # # L is a local variable of the function reverse, so it is visible within this scope # Use the print command to see its value (L has been declared but not # initialized, so the current contents are garbage; the value may vary from run to run.) # (gdb) print L $3 = 32767 # # R is a local variable of the function reverse, so it is visible within this scope # Use the print command to see its value (R has been declared but not # initialized, so the current contents are garbage; the value may vary from run to run.) # (gdb) print R $4 = -7360 # # Use the step command to execute the next statement. # (gdb) step 20 result = (char *) malloc(strlen(s)+1); # # Use the step command to execute the next statement. # (gdb) step 23 strcpy(result,s); # # print the value of s before executing line 23 (hasn't changed) # (gdb) print s $5 = 0x7fffffffe2d0 "hello\n" # # print the value of result before executing line 23 (appears to be the empty string) # (gdb) print result $6 = 0x602010 "" # # Use the next command to proceed to the next statement within a function (or to step over rather than into a function call) # similar to step, but function calls that appear within the line of code are executed without stopping # see https://sourceware.org/gdb/current/onlinedocs/gdb/Continuing-and-Stepping.html#Continuing-and-Stepping # (gdb) next 25 L = 0; # # print the value of result (after executing line 23) # (gdb) print result $7 = 0x602010 "hello\n" # # Use the step command to execute the next statement # (gdb) step 26 R = strlen(result); # # Use the step command to execute the next statement # (gdb) step 28 while (L < R) { # # Use the step command to execute the next statement # (gdb) step 29 ch = result[L]; # # print the current value of L # (gdb) print L $8 = 0 # # print the current value of R (obtained from executing line 26) # length of result, h-e-l-l-o-\n-\0, is 6 (exclude ending \0) # (gdb) print R $9 = 6 # # Use the step command to execute the next statement # (gdb) step 30 result[L] = result[R]; # # print the current value of ch (obtained from executing line 29) # (gdb) print ch $10 = 104 'h' # # Use the step command to execute the next statement # (gdb) step 31 result[R] = ch; # # print the value contained at result[L] (obtained from executing line 30) # result[6] is the 7th position in the array, or the \0 character, so we went too far # (gdb) print result[L] $11 = 0 '\000' # # print the value contained at result[R] # (gdb) print result[R] $12 = 0 '\000' # # Use the step command to execute the next statement # (gdb) step 32 L++; R--; # # print the value contained at result[R] # (gdb) print result[R] $13 = 104 'h' # # Use the step command to execute the next statement # (gdb) step 28 while (L < R) { # # Use the step command to execute the next statement # (gdb) step 29 ch = result[L]; # # Use the step command to execute the next statement # (gdb) step 30 result[L] = result[R]; # # Use the step command to execute the next statement # (gdb) step 31 result[R] = ch; # # Use the step command to execute the next statement # (gdb) step 32 L++; R--; # # Use the step command to execute the next statement # (gdb) step 28 while (L < R) { # # print the current value of L # (gdb) print L $14 = 2 # # print the current value of R # (gdb) print R $15 = 4 # # print the current value of s # (gdb) print s $16 = 0x7fffffffe2d0 "hello\n" # # print the current value of result # appears to be the empty string because \0 is in position 0 of the array # (gdb) print result $17 = 0x602010 "" # # try to examine the value of rev_line, show the letters are actually there # see https://sourceware.org/gdb/current/onlinedocs/gdb/Memory.html#Memory # see https://sourceware.org/gdb/current/onlinedocs/gdb/Output-Formats.html#Output-Formats # (gdb) x /10c result 0x602010: 0 '\000' 10 '\n' 108 'l' 108 'l' 111 'o' 101 'e' 104 'h' 0 '\000' 0x602018: 0 '\000' 0 '\000' # # use finish to run the function reverse until its end # see https://sourceware.org/gdb/current/onlinedocs/gdb/Continuing-and-Stepping.html#Continuing-and-Stepping # (gdb) finish Run till exit from #0 reverse (s=0x7fffffffe2d0 "hello\n") at reverse2.c:28 0x00000000004007d1 in main () at reverse2.c:48 48 rev_line = reverse(line); Value returned is $18 = 0x602010 "" # # the list command is centered on where reverse returned with a value (line 48) # (gdb) list 43 char * rev_line; /* backwards copy from reverse function */ 44 45 printf("Please enter a string: "); 46 fgets(line, MAX_STR, stdin); 47 48 rev_line = reverse(line); 49 50 printf("The original string was: >%s<\n", line); 51 printf("Backwards, that string is: >%s<\n", rev_line); 52 printf("Thank you for trying our program.\n"); # # print the value of line # note all the random junk in some of the cells of the array # (gdb) print line $19 = "hello\n\000\000`\343\377\377\377\177\000\000\070\001\301K3\000\000\000X\326\377\367\377\177\000\000}\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000m\b@\000\000\000\000\000\277", '\000' , " \b@\000\000\000\000\000\360\005@\000\000\000\000\000 \344\377\377" # # print the value of rev_line # (gdb) print rev_line $20 = 0x0 # # try to examine the value of rev_line # see https://sourceware.org/gdb/current/onlinedocs/gdb/Memory.html#Memory # see https://sourceware.org/gdb/current/onlinedocs/gdb/Output-Formats.html#Output-Formats # (gdb) x /10x rev_line 0x0: Cannot access memory at address 0x0 # # Use the step command to execute the next statement (finish the assignment of line 48) # (gdb) step 50 printf("The original string was: >%s<\n", line); # # try to examine the value of rev_line (10 characters' worth) # see https://sourceware.org/gdb/current/onlinedocs/gdb/Memory.html#Memory # see https://sourceware.org/gdb/current/onlinedocs/gdb/Output-Formats.html#Output-Formats # (gdb) x /10c rev_line 0x602010: 0 '\000' 10 '\n' 111 'o' 108 'l' 108 'l' 101 'e' 104 'h' 0 '\000' 0x602018: 0 '\000' 0 '\000' # # Use the continue command to keep going (resume program execution until your program completes normally) # (gdb) continue Continuing. The original string was: >hello < Backwards, that string is: >< Thank you for trying our program. [Inferior 1 (process 23802) exited normally] # # quit gdb # (gdb) quit $