1This is a tutorial/unittest for gdb's reverse debugging feature. It is a new 2feature that allows users to take a snapshot of the machine state, continue 3until a later stage of the program, then return to the previously recorded 4state and execute again. An ideal usage case is to help track down the reason 5why a memory location is clobbered. 6 7In the sample below, the "clobber" function trashes a neighboring variable "p" 8on the stack next to the "values" variable, and the program will crash at 9line 42 when "p" is being dereferenced. 10 11 18 #include <stdio.h> 12 19 #include <stdlib.h> 13 20 14 21 #define ARRAY_LENGTH 10 15 22 16 23 int flag; 17 24 18 25 void clobber(int *array, int size) { 19 26 /* Make sure it clobbers something. */ 20 27 array[-1] = 0x123; 21 28 array[size] = 0x123; 22 29 } 23 30 24 31 int main(void) { 25 32 int values[ARRAY_LENGTH]; 26 33 int *p = (int *) malloc(sizeof(int)); 27 34 *p = 10; 28 35 29 36 while (!flag) { 30 37 sleep(1); 31 38 } 32 39 33 40 /* Set a breakpint here: "b main.c:41" */ 34 41 clobber(values, ARRAY_LENGTH); 35 42 printf("*p = %d\n", *p); 36 43 free(p); 37 44 38 45 return 0; 39 46 } 40 41The test program can be built/installed on the device by doing: 42 43> mmm development/tutorials/ReverseDebug 44> adb sync 45> adb shell reverse_debug 46 47In another window the following command can be used to attach to the running 48program: 49 50> gdbclient reverse_debug :5039 reverse_debug 51[1] 12802 52Attached; pid = 1842 53Listening on port 5039 54GNU gdb (GDB) 7.6 55Copyright (C) 2013 Free Software Foundation, Inc. 56License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 57This is free software: you are free to change and redistribute it. 58There is NO WARRANTY, to the extent permitted by law. Type "show copying" 59and "show warranty" for details. 60This GDB was configured as "--host=x86_64-linux-gnu --target=arm-linux-android". 61For bug reporting instructions, please see: 62<http://source.android.com/source/report-bugs.html>... 63Reading symbols from /usr/local/google/work/master/out/target/product/manta/symbols/system/bin/reverse_debug...done. 64Remote debugging from host 127.0.0.1 65nanosleep () at bionic/libc/arch-arm/syscalls/nanosleep.S:10 6610 mov r7, ip 67 68==== 69 70Now set a breakpoint on line 41 and set flag to 1 so that the program can 71 continue. 72 73(gdb) b main.c:41 74Breakpoint 1 at 0xb6f174a8: file development/tutorials/ReverseDebug/main.c, line 41. 75(gdb) p flag=1 76$1 = 1 77(gdb) c 78Continuing. 79 80==== 81 82Now try the new "record" command to take a snapshot of the machine state. 83 84Breakpoint 1, main () at development/tutorials/ReverseDebug/main.c:41 8541 clobber(values, ARRAY_LENGTH); 86(gdb) record 87(gdb) c 88Continuing. 89 90==== 91 92Now the program crashes as expected as "p" has been clobbered. The 93"reverse-continue" command will bring the program back to line 41 and let you 94replay each instruction from there. 95 96Program received signal SIGSEGV, Segmentation fault. 970xb6f174bc in main () at development/tutorials/ReverseDebug/main.c:42 9842 printf("*p = %d\n", *p); 99(gdb) reverse-continue 100Continuing. 101 102No more reverse-execution history. 103main () at development/tutorials/ReverseDebug/main.c:41 10441 clobber(values, ARRAY_LENGTH); 105 106 107==== 108 109Now let's add a watch point at "&p" to hopefully catch the clobber on the spot: 110 111(gdb) watch *(&p) 112Hardware watchpoint 2: *(&p) 113(gdb) c 114Continuing. 115Hardware watchpoint 2: *(&p) 116 117==== 118 119And here it is: 120 121Old value = (int *) 0xb728c020 122New value = (int *) 0x123 1230xb6f17440 in clobber (array=0xbebcaab0, size=10) 124 at development/tutorials/ReverseDebug/main.c:28 12528 array[size] = 0x123; 126 127 128=============================== 129 130That said, reverse debugging on ARM is still in the infant stage. Currently 131(as of gdb 7.6) it only recognizes ARM instructions and will punt on all 132Thumb(2) instructions. To give it a try you will need to recompile your 133program in ARM mode. To do that you have to add the ".arm" suffix to the 134desired file in Android.mk: 135 136LOCAL_SRC_FILES:= main.c.arm 137 138