README.txt
1 This is a tutorial/unittest for gdb's reverse debugging feature. It is a new
2 feature that allows users to take a snapshot of the machine state, continue
3 until a later stage of the program, then return to the previously recorded
4 state and execute again. An ideal usage case is to help track down the reason
5 why a memory location is clobbered.
6
7 In the sample below, the "clobber" function trashes a neighboring variable "p"
8 on the stack next to the "values" variable, and the program will crash at
9 line 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
41 The 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
47 In another window the following command can be used to attach to the running
48 program:
49
50 > gdbclient reverse_debug :5039 reverse_debug
51 [1] 12802
52 Attached; pid = 1842
53 Listening on port 5039
54 GNU gdb (GDB) 7.6
55 Copyright (C) 2013 Free Software Foundation, Inc.
56 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
57 This is free software: you are free to change and redistribute it.
58 There is NO WARRANTY, to the extent permitted by law. Type "show copying"
59 and "show warranty" for details.
60 This GDB was configured as "--host=x86_64-linux-gnu --target=arm-linux-android".
61 For bug reporting instructions, please see:
62 <http://source.android.com/source/report-bugs.html>...
63 Reading symbols from /usr/local/google/work/master/out/target/product/manta/symbols/system/bin/reverse_debug...done.
64 Remote debugging from host 127.0.0.1
65 nanosleep () at bionic/libc/arch-arm/syscalls/nanosleep.S:10
66 10 mov r7, ip
67
68 ====
69
70 Now 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
74 Breakpoint 1 at 0xb6f174a8: file development/tutorials/ReverseDebug/main.c, line 41.
75 (gdb) p flag=1
76 $1 = 1
77 (gdb) c
78 Continuing.
79
80 ====
81
82 Now try the new "record" command to take a snapshot of the machine state.
83
84 Breakpoint 1, main () at development/tutorials/ReverseDebug/main.c:41
85 41 clobber(values, ARRAY_LENGTH);
86 (gdb) record
87 (gdb) c
88 Continuing.
89
90 ====
91
92 Now 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
94 replay each instruction from there.
95
96 Program received signal SIGSEGV, Segmentation fault.
97 0xb6f174bc in main () at development/tutorials/ReverseDebug/main.c:42
98 42 printf("*p = %d\n", *p);
99 (gdb) reverse-continue
100 Continuing.
101
102 No more reverse-execution history.
103 main () at development/tutorials/ReverseDebug/main.c:41
104 41 clobber(values, ARRAY_LENGTH);
105
106
107 ====
108
109 Now let's add a watch point at "&p" to hopefully catch the clobber on the spot:
110
111 (gdb) watch *(&p)
112 Hardware watchpoint 2: *(&p)
113 (gdb) c
114 Continuing.
115 Hardware watchpoint 2: *(&p)
116
117 ====
118
119 And here it is:
120
121 Old value = (int *) 0xb728c020
122 New value = (int *) 0x123
123 0xb6f17440 in clobber (array=0xbebcaab0, size=10)
124 at development/tutorials/ReverseDebug/main.c:28
125 28 array[size] = 0x123;
126
127
128 ===============================
129
130 That 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
132 Thumb(2) instructions. To give it a try you will need to recompile your
133 program in ARM mode. To do that you have to add the ".arm" suffix to the
134 desired file in Android.mk:
135
136 LOCAL_SRC_FILES:= main.c.arm
137
138