# 2014 January 31 # # Using GDB (debugger) on first variation of reverse program (reverse1.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 reverse1.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. # # The run command begins execution of the program # (gdb) run Starting program: /homes/campbl4/GDB_Demo/reverse Please enter a string: hello # # The segmentation fault happened around the strcpy command. # Program received signal SIGSEGV, Segmentation fault. 0x000000334bc861c0 in __strcpy_sse2 () from /lib64/libc.so.6 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 0x000000334bc861c0 in __strcpy_sse2 () from /lib64/libc.so.6 #1 0x00000000004006b7 in reverse (s=0x7fffffffe2d0 "hello\n") at reverse1.c:20 #2 0x0000000000400765 in main () at reverse1.c:45 # # The up command will unwind the stack of function calls one level at a time. # Now we are focused on reverse. # (gdb) up #1 0x00000000004006b7 in reverse (s=0x7fffffffe2d0 "hello\n") at reverse1.c:20 20 strcpy(result,s); # # The list command lists the source code if the executable was compiled with -g # Thanks to the up command we are now focused on the reverse function, within # which the strcpy command was called (at line 20). The list command centers # the listing around line 20 so we can see the context of this line of code. # (gdb) list 15 char * result = NULL; /* the reversed string */ 16 int L, R; 17 char ch; 18 19 /* copy original string then reverse and return the copy */ 20 strcpy(result,s); 21 22 L = 0; 23 R = strlen(result); 24 # # The up command will unwind the stack of function calls one level at a time. # Now we are focused on main. Main called reverse at line 45. # (gdb) up #2 0x0000000000400765 in main () at reverse1.c:45 45 rev_line = reverse(line); # # The listing is now centered on line 45. # (gdb) list 40 char * rev_line; /* backwards copy from reverse function */ 41 42 printf("Please enter a string: "); 43 fgets(line, MAX_STR, stdin); 44 45 rev_line = reverse(line); 46 47 printf("The original string was: >%s<\n", line); 48 printf("Backwards, that string is: >%s<\n", rev_line); 49 printf("Thank you for trying our program.\n"); # # The down command goes back down the stack (here, from main to reverse). # (gdb) down #1 0x00000000004006b7 in reverse (s=0x7fffffffe2d0 "hello\n") at reverse1.c:20 20 strcpy(result,s); # # Again, listing is centered on line 20. # (gdb) list 15 char * result = NULL; /* the reversed string */ 16 int L, R; 17 char ch; 18 19 /* copy original string then reverse and return the copy */ 20 strcpy(result,s); 21 22 L = 0; 23 R = strlen(result); 24 # # Hitting return at the (gdb) prompt will normally repeat the last command (here, list) # (gdb) 25 while (L < R) { 26 ch = result[L]; 27 result[L] = result[R]; 28 result[R] = ch; 29 L++; R--; 30 } 31 32 return result; 33 } 34 # # Hitting return at the (gdb) prompt will normally repeat the last command (here, list) # (gdb) 35 36 /* Ask the user for a string, then print it forwards and backwards. */ 37 int main() { 38 39 char line[MAX_STR]; /* original input line */ 40 char * rev_line; /* backwards copy from reverse function */ 41 42 printf("Please enter a string: "); 43 fgets(line, MAX_STR, stdin); 44 # # Hitting return at the (gdb) prompt will normally repeat the last command (here, list) # (gdb) 45 rev_line = reverse(line); 46 47 printf("The original string was: >%s<\n", line); 48 printf("Backwards, that string is: >%s<\n", rev_line); 49 printf("Thank you for trying our program.\n"); 50 51 return 0; 52 } # # Again, backtrace shows the series of calls before the seg fault happened. # (gdb) backtrace #0 0x000000334bc861c0 in __strcpy_sse2 () from /lib64/libc.so.6 #1 0x00000000004006b7 in reverse (s=0x7fffffffe2d0 "hello\n") at reverse1.c:20 #2 0x0000000000400765 in main () at reverse1.c:45 # # List can also take a line number as an argument. The code is now centered on line 19. # (gdb) list 19 14 15 char * result = NULL; /* the reversed string */ 16 int L, R; 17 char ch; 18 19 /* copy original string then reverse and return the copy */ 20 strcpy(result,s); 21 22 L = 0; 23 R = strlen(result); # # The value of variables within the current scope can be printed. # (gdb) print s $1 = 0x7fffffffe2d0 "hello\n" # # The value of variables within the current scope can be printed. # (gdb) print result $2 = 0x0 # # The quit command will quit GDB. # (gdb) quit A debugging session is active. Inferior 1 [process 23744] will be killed. Quit anyway? (y or n) y $