summaryrefslogtreecommitdiffstats
path: root/tutorials
diff options
context:
space:
mode:
authorBen Cheng <bccheng@google.com>2013-06-24 14:48:19 -0700
committerBen Cheng <bccheng@google.com>2013-06-24 14:48:19 -0700
commit73644dd2c873ca0bfea3b611ba56c76b93f6bdba (patch)
tree883160a6e0065ab68fdb8331bfa3f598ba1cffd8 /tutorials
parent434ffc1f30af95f27562c9adf3bb16c8bdca10da (diff)
downloadandroid_development-73644dd2c873ca0bfea3b611ba56c76b93f6bdba.tar.gz
android_development-73644dd2c873ca0bfea3b611ba56c76b93f6bdba.tar.bz2
android_development-73644dd2c873ca0bfea3b611ba56c76b93f6bdba.zip
Add a new example/unittest for GDB's reverse debugging feature.
Change-Id: Ic55343957cd35dc41d2dcf9f436d1940cd454084
Diffstat (limited to 'tutorials')
-rw-r--r--tutorials/ReverseDebug/Android.mk28
-rw-r--r--tutorials/ReverseDebug/README.txt137
-rw-r--r--tutorials/ReverseDebug/main.c46
3 files changed, 211 insertions, 0 deletions
diff --git a/tutorials/ReverseDebug/Android.mk b/tutorials/ReverseDebug/Android.mk
new file mode 100644
index 000000000..586daf85a
--- /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 000000000..2578a4d1a
--- /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 000000000..5ae18901b
--- /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;
+}