Add a new example/unittest for GDB's reverse debugging feature.

Change-Id: Ic55343957cd35dc41d2dcf9f436d1940cd454084
diff --git a/tutorials/ReverseDebug/Android.mk b/tutorials/ReverseDebug/Android.mk
new file mode 100644
index 0000000..586daf8
--- /dev/null
+++ b/tutorials/ReverseDebug/Android.mk
@@ -0,0 +1,28 @@
+# Copyright (C) 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+ifneq ($(filter arm ,$(TARGET_ARCH)),)
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= main.c.arm
+
+LOCAL_CFLAGS := -std=gnu99 -O0
+
+LOCAL_MODULE := reverse_debug
+
+include $(BUILD_EXECUTABLE)
+
+endif # arm in TARGET_ARCH
diff --git a/tutorials/ReverseDebug/README.txt b/tutorials/ReverseDebug/README.txt
new file mode 100644
index 0000000..2578a4d
--- /dev/null
+++ b/tutorials/ReverseDebug/README.txt
@@ -0,0 +1,137 @@
+This is a tutorial/unittest for gdb's reverse debugging feature. It is a new
+feature that allows users to take a snapshot of the machine state, continue
+until a later stage of the program, then return to the previously recorded
+state and execute again. An ideal usage case is to help track down the reason
+why a memory location is clobbered. 
+
+In the sample below, the "clobber" function trashes a neighboring variable "p"
+on the stack next to the "values" variable, and the program will crash at
+line 42 when "p" is being dereferenced.
+
+ 18 #include <stdio.h>
+ 19 #include <stdlib.h>
+ 20 
+ 21 #define ARRAY_LENGTH 10
+ 22 
+ 23 int flag;
+ 24 
+ 25 void clobber(int *array, int size) {
+ 26     /* Make sure it clobbers something. */
+ 27     array[-1] = 0x123;
+ 28     array[size] = 0x123;
+ 29 }
+ 30 
+ 31 int main(void) {
+ 32     int values[ARRAY_LENGTH];
+ 33     int *p = (int *) malloc(sizeof(int));
+ 34     *p = 10;
+ 35 
+ 36     while (!flag) {
+ 37         sleep(1);
+ 38     }
+ 39 
+ 40     /* Set a breakpint here: "b main.c:41" */
+ 41     clobber(values, ARRAY_LENGTH);
+ 42     printf("*p = %d\n", *p);
+ 43     free(p);
+ 44 
+ 45     return 0;
+ 46 }
+
+The test program can be built/installed on the device by doing:
+
+> mmm development/tutorials/ReverseDebug
+> adb sync
+> adb shell reverse_debug
+
+In another window the following command can be used to attach to the running
+program:
+
+> gdbclient reverse_debug :5039 reverse_debug
+[1] 12802
+Attached; pid = 1842
+Listening on port 5039
+GNU gdb (GDB) 7.6
+Copyright (C) 2013 Free Software Foundation, Inc.
+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
+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 "--host=x86_64-linux-gnu --target=arm-linux-android".
+For bug reporting instructions, please see:
+<http://source.android.com/source/report-bugs.html>...
+Reading symbols from /usr/local/google/work/master/out/target/product/manta/symbols/system/bin/reverse_debug...done.
+Remote debugging from host 127.0.0.1
+nanosleep () at bionic/libc/arch-arm/syscalls/nanosleep.S:10
+10      mov     r7, ip
+
+====
+
+Now set a breakpoint on line 41 and set flag to 1 so that the program can
+ continue. 
+
+(gdb) b main.c:41
+Breakpoint 1 at 0xb6f174a8: file development/tutorials/ReverseDebug/main.c, line 41.
+(gdb) p flag=1
+$1 = 1
+(gdb) c
+Continuing.
+
+====
+
+Now try the new "record" command to take a snapshot of the machine state.
+
+Breakpoint 1, main () at development/tutorials/ReverseDebug/main.c:41
+41      clobber(values, ARRAY_LENGTH);
+(gdb) record
+(gdb) c
+Continuing.
+
+====
+
+Now the program crashes as expected as "p" has been clobbered. The
+"reverse-continue" command will bring the program back to line 41 and let you
+replay each instruction from there.
+
+Program received signal SIGSEGV, Segmentation fault.
+0xb6f174bc in main () at development/tutorials/ReverseDebug/main.c:42
+42      printf("*p = %d\n", *p);
+(gdb) reverse-continue
+Continuing.
+
+No more reverse-execution history.
+main () at development/tutorials/ReverseDebug/main.c:41
+41      clobber(values, ARRAY_LENGTH);
+
+
+====
+
+Now let's add a watch point at "&p" to hopefully catch the clobber on the spot:
+ 
+(gdb) watch *(&p)
+Hardware watchpoint 2: *(&p)
+(gdb) c
+Continuing.
+Hardware watchpoint 2: *(&p)
+
+====
+
+And here it is:
+
+Old value = (int *) 0xb728c020
+New value = (int *) 0x123
+0xb6f17440 in clobber (array=0xbebcaab0, size=10)
+    at development/tutorials/ReverseDebug/main.c:28
+28      array[size] = 0x123;
+
+
+===============================
+
+That said, reverse debugging on ARM is still in the infant stage. Currently
+(as of gdb 7.6) it only recognizes ARM instructions and will punt on all
+Thumb(2) instructions. To give it a try you will need to recompile your
+program in ARM mode. To do that you have to add the ".arm" suffix to the
+desired file in Android.mk:
+
+LOCAL_SRC_FILES:= main.c.arm
+
diff --git a/tutorials/ReverseDebug/main.c b/tutorials/ReverseDebug/main.c
new file mode 100644
index 0000000..5ae1890
--- /dev/null
+++ b/tutorials/ReverseDebug/main.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define ARRAY_LENGTH 10
+
+int flag;
+
+void clobber(int *array, int size) {
+    /* Make sure it clobbers something. */
+    array[-1] = 0x123;
+    array[size] = 0x123;
+}
+
+int main(void) {
+    int values[ARRAY_LENGTH];
+    int *p = (int *) malloc(sizeof(int));
+    *p = 10;
+
+    while (!flag) {
+        sleep(1);
+    }
+
+    /* Set a breakpint here: "b main.c:41" */
+    clobber(values, ARRAY_LENGTH);
+    printf("*p = %d\n", *p);
+    free(p);
+
+    return 0;
+}