diff options
author | Ben Cheng <bccheng@google.com> | 2013-06-24 14:48:19 -0700 |
---|---|---|
committer | Ben Cheng <bccheng@google.com> | 2013-06-24 14:48:19 -0700 |
commit | 73644dd2c873ca0bfea3b611ba56c76b93f6bdba (patch) | |
tree | 883160a6e0065ab68fdb8331bfa3f598ba1cffd8 /tutorials | |
parent | 434ffc1f30af95f27562c9adf3bb16c8bdca10da (diff) | |
download | android_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.mk | 28 | ||||
-rw-r--r-- | tutorials/ReverseDebug/README.txt | 137 | ||||
-rw-r--r-- | tutorials/ReverseDebug/main.c | 46 |
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; +} |