aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite
diff options
context:
space:
mode:
authorToshihito Kikuchi <k.toshihito@yahoo.de>2016-06-09 22:47:42 -0700
committerToshihito Kikuchi <k.toshihito@yahoo.de>2016-06-09 22:50:47 -0700
commitbb556f1facb86cdd1591d490f2d2d670bdd5a1ee (patch)
treeccc99d237487ee5952ff66d92a4f2a207dd41f6a /gdb/testsuite
parentc040f3fb55315f06ceb9e6de6ac167a95a445ace (diff)
downloadgdb-bb556f1facb86cdd1591d490f2d2d670bdd5a1ee.zip
gdb-bb556f1facb86cdd1591d490f2d2d670bdd5a1ee.tar.gz
gdb-bb556f1facb86cdd1591d490f2d2d670bdd5a1ee.tar.bz2
Add negative repeat count to 'x' command
This change adds support for specifying a negative repeat count to all the formats of the 'x' command to examine memory backward. A new testcase 'examine-backward' is added to cover this new feature. Here's the example output from the new feature: <format 'i'> (gdb) bt #0 Func1 (n=42, p=0x40432e "hogehoge") at main.cpp:5 #1 0x00000000004041fa in main (argc=1, argv=0x7fffffffdff8) at main.cpp:19 (gdb) x/-4i 0x4041fa 0x4041e5 <main(int, char**)+11>: mov %rsi,-0x10(%rbp) 0x4041e9 <main(int, char**)+15>: lea 0x13e(%rip),%rsi 0x4041f0 <main(int, char**)+22>: mov $0x2a,%edi 0x4041f5 <main(int, char**)+27>: callq 0x404147 <format 'x'> (gdb) x/-4xw 0x404200 0x4041f0 <main(int, char**)+22>: 0x00002abf 0xff4de800 0x76e8ffff 0xb8ffffff (gdb) x/-4 0x4041e0 <main(int, char**)+6>: 0x7d8910ec 0x758948fc 0x358d48f0 0x0000013e gdb/ChangeLog: * NEWS: Mention that GDB now supports a negative repeat count in the 'x' command. * printcmd.c (decode_format): Allow '-' in the parameter "string_ptr" to accept a negative repeat count. (find_instruction_backward): New function. (read_memory_backward): New function. (integer_is_zero): New function. (find_string_backward): New function. (do_examine): Use new functions to examine memory backward. (_initialize_printcmd): Mention that 'x' command supports a negative repeat count. gdb/doc/ChangeLog: * gdb.texinfo (Examining Memory): Document negative repeat count in the 'x' command. gdb/testsuite/ChangeLog: * gdb.base/examine-backward.c: New file. * gdb.base/examine-backward.exp: New file.
Diffstat (limited to 'gdb/testsuite')
-rw-r--r--gdb/testsuite/ChangeLog5
-rw-r--r--gdb/testsuite/gdb.base/examine-backward.c106
-rw-r--r--gdb/testsuite/gdb.base/examine-backward.exp324
3 files changed, 435 insertions, 0 deletions
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 98a798b..19b00a1 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2016-06-09 Toshihito Kikuchi <k.toshihito@yahoo.de>
+
+ * gdb.base/examine-backward.c: New file.
+ * gdb.base/examine-backward.exp: New file.
+
2016-06-06 Simon Marchi <simon.marchi@ericsson.com>
* gdb.mi/mi-record-changed.exp: Adjust =record-started output
diff --git a/gdb/testsuite/gdb.base/examine-backward.c b/gdb/testsuite/gdb.base/examine-backward.c
new file mode 100644
index 0000000..b338503
--- /dev/null
+++ b/gdb/testsuite/gdb.base/examine-backward.c
@@ -0,0 +1,106 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2015-2016 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/*
+Define TestStrings, TestStringsH, and TestStringsW to test utf8, utf16,
+and utf32 strings respectively.
+To avoid compile errors due to old compiler mode, we don't use string
+literals. The content of each array is the same as followings:
+
+ const char TestStrings[] = {
+ "ABCD"
+ "EFGHIJKLMNOPQRSTUVWXYZ\0"
+ "\0"
+ "\0"
+ "\u307B\u3052\u307B\u3052\0"
+ "012345678901234567890123456789\0"
+ "!!!!!!\0"
+ };
+*/
+
+const char TestStrings[] = {
+ 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
+ 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
+ 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+ 0x59, 0x5a, 0x00, 0x00, 0x00, 0xe3, 0x81, 0xbb,
+ 0xe3, 0x81, 0x92, 0xe3, 0x81, 0xbb, 0xe3, 0x81,
+ 0x92, 0x00, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
+ 0x36, 0x37, 0x38, 0x39, 0x30, 0x31, 0x32, 0x33,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x31,
+ 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x00, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x00,
+ 0x00
+};
+
+const short TestStringsH[] = {
+ 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048,
+ 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
+ 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
+ 0x0059, 0x005a, 0x0000, 0x0000, 0x0000, 0x307b, 0x3052, 0x307b,
+ 0x3052, 0x0000, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
+ 0x0036, 0x0037, 0x0038, 0x0039, 0x0030, 0x0031, 0x0032, 0x0033,
+ 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x0030, 0x0031,
+ 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039,
+ 0x0000, 0x0021, 0x0021, 0x0021, 0x0021, 0x0021, 0x0021, 0x0000,
+ 0x0000
+};
+
+const int TestStringsW[] = {
+ 0x00000041, 0x00000042, 0x00000043, 0x00000044,
+ 0x00000045, 0x00000046, 0x00000047, 0x00000048,
+ 0x00000049, 0x0000004a, 0x0000004b, 0x0000004c,
+ 0x0000004d, 0x0000004e, 0x0000004f, 0x00000050,
+ 0x00000051, 0x00000052, 0x00000053, 0x00000054,
+ 0x00000055, 0x00000056, 0x00000057, 0x00000058,
+ 0x00000059, 0x0000005a, 0x00000000, 0x00000000,
+ 0x00000000, 0x0000307b, 0x00003052, 0x0000307b,
+ 0x00003052, 0x00000000, 0x00000030, 0x00000031,
+ 0x00000032, 0x00000033, 0x00000034, 0x00000035,
+ 0x00000036, 0x00000037, 0x00000038, 0x00000039,
+ 0x00000030, 0x00000031, 0x00000032, 0x00000033,
+ 0x00000034, 0x00000035, 0x00000036, 0x00000037,
+ 0x00000038, 0x00000039, 0x00000030, 0x00000031,
+ 0x00000032, 0x00000033, 0x00000034, 0x00000035,
+ 0x00000036, 0x00000037, 0x00000038, 0x00000039,
+ 0x00000000, 0x00000021, 0x00000021, 0x00000021,
+ 0x00000021, 0x00000021, 0x00000021, 0x00000000,
+ 0x00000000
+};
+
+int
+main (void)
+{
+ /* Backward disassemble test requires at least 20 instructions in
+ this function. Adding a simple bubble sort. */
+ int i, j;
+ int n[] = {3, 1, 4, 1, 5, 9};
+ int len = sizeof (n) / sizeof (n[0]);
+
+ for (i = 0; i < len - 1; ++i)
+ {
+ for (j = i; j < len; ++j)
+ {
+ if (n[j] < n[i])
+ {
+ int tmp = n[i];
+ n[i] = n[j];
+ n[j] = tmp;
+ }
+ }
+ }
+ return 42;
+}
diff --git a/gdb/testsuite/gdb.base/examine-backward.exp b/gdb/testsuite/gdb.base/examine-backward.exp
new file mode 100644
index 0000000..e03cbfd
--- /dev/null
+++ b/gdb/testsuite/gdb.base/examine-backward.exp
@@ -0,0 +1,324 @@
+# Copyright 2015-2016 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# This testsuite is to test examining memory backward by specifying a negative
+# number in the 'x' command.
+
+standard_testfile
+if { [prepare_for_testing "failed to prepare for examine-backward" \
+ ${testfile} ${srcfile}] } {
+ return -1
+}
+
+if ![runto_main] {
+ untested "could not run to main"
+ return -1
+}
+
+proc get_first_mapped_address {} {
+ global gdb_prompt
+
+ set addr "0"
+ gdb_test_multiple "info proc mappings" "info proc mappings" {
+ -re "objfile\[\r\n\t \]+(0x\[0-9a-fA-F\]+).*\[\r\n\]*$gdb_prompt $" {
+ set addr $expect_out(1,string)
+ }
+ -re "$gdb_prompt $" {
+ unsupported "Current target does not support 'info proc mappings'"
+ }
+ }
+ return ${addr}
+}
+
+with_test_prefix "invalid format" {
+ gdb_test "x/- 10xb main" "Invalid number \"10xb\"\." \
+ "a whitespace after a leading hyphen"
+ gdb_test "x/--10xb main" "Invalid number \"10xb\"\." \
+ "double hyphen"
+ gdb_test "x/-a10xb main" "Invalid number \"10xb\"\." \
+ "an alphabet after a leading hyphen"
+ gdb_test_no_output "x/-0i main" "zero with backward disassemble"
+ gdb_test_no_output "x/-0sh main" "zero with backward examine string"
+}
+
+with_test_prefix "memory page boundary" {
+ set boundary [get_first_mapped_address]
+ if {![is_address_zero_readable] && $boundary != 0} {
+ gdb_test_no_output "set print elements 0"
+ gdb_test_sequence "x/3s ${boundary}" "take 3 strings forward" {
+ "0x"
+ "0x"
+ "0x"
+ }
+ gdb_test_sequence "x/-4s" "take 4 strings backward" {
+ "Cannot access memory at address 0x"
+ "0x"
+ "0x"
+ "0x"
+ }
+ gdb_test_sequence "x/3s ${boundary}" "take 3 strings forward again" {
+ "0x"
+ "0x"
+ "0x"
+ }
+ gdb_test_sequence "x/-3s" "take 3 strings backward" {
+ "Cannot access memory at address 0x"
+ "0x"
+ "0x"
+ "0x"
+ }
+ }
+}
+
+with_test_prefix "address zero boundary" {
+ if {[is_address_zero_readable]} {
+ set address_zero "0x0"
+ set byte "\t0x\[0-9a-f\]+"
+ gdb_test "x/3xb ${address_zero}" \
+ "0x\[0-9a-f\]+00.*:${byte}${byte}${byte}" \
+ "examine 3 bytes forward from ${address_zero}"
+ gdb_test "x/-6x" \
+ "0x\[0-9a-f\]+fd.*:${byte}${byte}${byte}${byte}${byte}${byte}" \
+ "examine 6 bytes backward"
+ gdb_test "x/-3x ${address_zero}" \
+ "0x\[0-9a-f\]+fd.*:${byte}${byte}${byte}" \
+ "examine 3 bytes backward from ${address_zero}"
+ }
+}
+
+gdb_test_no_output "set charset ASCII"
+
+with_test_prefix "char-width=1, print-max=20" {
+ gdb_test_no_output "set print elements 20"
+ gdb_test_sequence "x/6s &TestStrings" "take 6 strings forward" {
+ "\"ABCDEFGHIJKLMNOPQRST\"\.\.\."
+ "\"UVWXYZ\""
+ "\"\""
+ "\"\""
+ "\"[^\"]+\""
+ "\"01234567890123456789\"\.\.\."
+ }
+ gdb_test "x/-1xb" "0x39" "take 1 char backward"
+ gdb_test_sequence "x/-6s" "take 6 strings backward" {
+ "\"ABCDEFGHIJKLMNOPQRST\"\.\.\."
+ "\"UVWXYZ\""
+ "\"\""
+ "\"\""
+ "\"[^\"]+\""
+ "\"01234567890123456789\"\.\.\."
+ }
+ gdb_test_sequence "x/6s &TestStrings" "take 6 strings forward again" {
+ "\"ABCDEFGHIJKLMNOPQRST\"\.\.\."
+ "\"UVWXYZ\""
+ "\"\""
+ "\"\""
+ "\"[^\"]+\""
+ "\"01234567890123456789\"\.\.\."
+ }
+ gdb_test "x/-xb" "0x39" "take 1 char backward again"
+ gdb_test "x/-s" "\"01234567890123456789\"\.\.\." \
+ "take 1 string backward (1/6)"
+ gdb_test "x/-s" "\".+\"" \
+ "take 1 string backward (2/6)"
+ gdb_test "x/-s" "\"\"" \
+ "take 1 string backward (3/6)"
+ gdb_test "x/-s" "\"\"" \
+ "take 1 string backward (4/6)"
+ gdb_test "x/-s" "\"GHIJKLMNOPQRSTUVWXYZ\"" \
+ "take 1 string backward (5/6)"
+ gdb_test "x/-s" "\"ABCDEFGHIJKLMNOPQRST\"\.\.\." \
+ "take 1 string backward (6/6)"
+}
+
+with_test_prefix "char-width=2, print-max=20" {
+ gdb_test_no_output "set print elements 20"
+ gdb_test_sequence "x/6sh &TestStringsH" "take 6 strings forward" {
+ "u\"ABCDEFGHIJKLMNOPQRST\"\.\.\."
+ "u\"UVWXYZ\""
+ "u\"\""
+ "u\"\""
+ "u\"[^\"]+\""
+ "u\"01234567890123456789\"\.\.\."
+ }
+ gdb_test "x/-1xh" "0x0039" "take 1 char backward"
+ gdb_test_sequence "x/-6sh" "take 6 strings backward" {
+ "u\"ABCDEFGHIJKLMNOPQRST\"\.\.\."
+ "u\"UVWXYZ\""
+ "u\"\""
+ "u\"\""
+ "u\"[^\"]+\""
+ "u\"01234567890123456789\"\.\.\."
+ }
+ gdb_test_sequence "x/6sh &TestStringsH" "take 6 strings forward again" {
+ "u\"ABCDEFGHIJKLMNOPQRST\"\.\.\."
+ "u\"UVWXYZ\""
+ "u\"\""
+ "u\"\""
+ "u\"[^\"]+\""
+ "u\"01234567890123456789\"\.\.\."
+ }
+ gdb_test "x/-xh" "0x0039" "take 1 char backward again"
+ gdb_test "x/-sh" "u\"01234567890123456789\"\.\.\." \
+ "take 1 string backward (1/6)"
+ gdb_test "x/-sh" "u\".+\"" \
+ "take 1 string backward (2/6)"
+ gdb_test "x/-sh" "u\"\"" \
+ "take 1 string backward (3/6)"
+ gdb_test "x/-sh" "u\"\"" \
+ "take 1 string backward (4/6)"
+ gdb_test "x/-sh" "u\"GHIJKLMNOPQRSTUVWXYZ\"" \
+ "take 1 string backward (5/6)"
+ gdb_test "x/-sh" "u\"ABCDEFGHIJKLMNOPQRST\"\.\.\." \
+ "take 1 string backward (6/6)"
+}
+
+with_test_prefix "char-width=4, print-max=20" {
+ gdb_test_no_output "set print elements 20"
+ gdb_test_sequence "x/6sw &TestStringsW" "take 6 strings forward" {
+ "U\"ABCDEFGHIJKLMNOPQRST\"\.\.\."
+ "U\"UVWXYZ\""
+ "U\"\""
+ "U\"\""
+ "U\"[^\"]+\""
+ "U\"01234567890123456789\"\.\.\."
+ }
+ gdb_test "x/-1xw" "0x00000039" "take 1 char backward"
+ gdb_test_sequence "x/-6sw" "take 6 strings backward" {
+ "U\"ABCDEFGHIJKLMNOPQRST\"\.\.\."
+ "U\"UVWXYZ\""
+ "U\"\""
+ "U\"\""
+ "U\"[^\"]+\""
+ "U\"01234567890123456789\"\.\.\."
+ }
+ gdb_test_sequence "x/6sw &TestStringsW" "take 6 strings forward again" {
+ "U\"ABCDEFGHIJKLMNOPQRST\"\.\.\."
+ "U\"UVWXYZ\""
+ "U\"\""
+ "U\"\""
+ "U\"[^\"]+\""
+ "U\"01234567890123456789\"\.\.\."
+ }
+ gdb_test "x/-xw" "0x00000039" "take 1 char backward again"
+ gdb_test "x/-sw" "U\"01234567890123456789\"\.\.\." \
+ "take 1 string backward (1/6)"
+ gdb_test "x/-sw" "U\".+\"" \
+ "take 1 string backward (2/6)"
+ gdb_test "x/-sw" "U\"\"" \
+ "take 1 string backward (3/6)"
+ gdb_test "x/-sw" "U\"\"" \
+ "take 1 string backward (4/6)"
+ gdb_test "x/-sw" "U\"GHIJKLMNOPQRSTUVWXYZ\"" \
+ "take 1 string backward (5/6)"
+ gdb_test "x/-sw" "U\"ABCDEFGHIJKLMNOPQRST\"\.\.\." \
+ "take 1 string backward (6/6)"
+}
+
+with_test_prefix "char-width=2, print-max=0" {
+ gdb_test_no_output "set print elements 0"
+ gdb_test_sequence "x/6sh &TestStringsH" "take 6 strings forward" {
+ "u\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\""
+ "u\"\""
+ "u\"\""
+ "u\"\\\\x307b\\\\x3052\\\\x307b\\\\x3052\""
+ "u\"012345678901234567890123456789\""
+ "u\"!!!!!!\""
+ }
+ gdb_test "x/-4xh" "0x0021\[\t \]+0x0021\[\t \]+0x0021\[\t \]+0x0000" \
+ "take 4 characters backward"
+ gdb_test_sequence "x/-6sh" "take 6 strings backward" {
+ "u\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\""
+ "u\"\""
+ "u\"\""
+ "u\"[^\"]+\""
+ "u\"012345678901234567890123456789\""
+ "u\"!!!!!!\""
+ }
+ gdb_test_sequence "x/6sh &TestStringsH" "take 6 strings forward again" {
+ "u\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\""
+ "u\"\""
+ "u\"\""
+ "u\"\\\\x307b\\\\x3052\\\\x307b\\\\x3052\""
+ "u\"012345678901234567890123456789\""
+ "u\"!!!!!!\""
+ }
+ gdb_test "x/-xh" "0x0000" "take 1 char backward"
+ gdb_test "x/-sh" "u\"!!!!!!\"" \
+ "take 1 string backward (1/6)"
+ gdb_test "x/-sh" "u\"012345678901234567890123456789\"" \
+ "take 1 string backward (2/6)"
+ gdb_test "x/-sh" "u\".+\"" \
+ "take 1 string backward (3/6)"
+ gdb_test "x/-sh" "u\"\"" \
+ "take 1 string backward (4/6)"
+ gdb_test "x/-sh" "u\"\"" \
+ "take 1 string backward (5/6)"
+ gdb_test "x/-sh" "u\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"" \
+ "take 1 string backward (6/6)"
+}
+
+with_test_prefix "char-width=1, print-max=4" {
+ gdb_test_no_output "set print elements 4"
+ gdb_test_sequence "x/9s &TestStrings" "take 9 strings forward" {
+ "\"ABCD\"\.\.\."
+ "\"EFGH\"\.\.\."
+ "\"IJKL\"\.\.\."
+ "\"MNOP\"\.\.\."
+ "\"QRST\"\.\.\."
+ "\"UVWX\"\.\.\."
+ "\"YZ\""
+ "\"\""
+ "\"\""
+ }
+ gdb_test "x/-xb" "0x00" "take 1 byte backward"
+ gdb_test_sequence "x/-4s" "take 4 strings backward (1/2)" {
+ "\"TUVW\"\.\.\."
+ "\"XYZ\""
+ "\"\""
+ "\"\""
+ }
+ gdb_test_sequence "x/-4s" "take 4 strings backward (2/2)" {
+ "\"CDEF\"\.\.\."
+ "\"GHIJ\"\.\.\."
+ "\"KLMN\"\.\.\."
+ "\"OPQR\"\.\.\."
+ }
+}
+
+with_test_prefix "backward disassemble general" {
+ set length_to_examine {1 2 3 4 10}
+ set disassmbly {}
+
+ gdb_test "x/i main" "0x\[0-9a-fA-F\]+ <main>:\t.*" \
+ "move the current position to main (x/i)"
+ gdb_test "x/-i" "0x\[0-9a-fA-F\]+ <main>:\t.*" \
+ "move the current position to main (x/-i)"
+ for {set i 0} {$i < [llength $length_to_examine]} {incr i} {
+ set len [lindex $length_to_examine $i]
+ set instructions [capture_command_output "x/${len}i" ""]
+ lappend disassmbly $instructions
+ }
+ for {set i 0} {$i < [llength $length_to_examine]} {incr i} {
+ set idx [expr [llength $length_to_examine] - $i - 1]
+ set len [lindex $length_to_examine $idx]
+ set actual [capture_command_output "x/-${len}i" ""]
+ set expected [lindex $disassmbly $idx]
+ if {$actual == $expected} {
+ pass "inst:$idx"
+ } else {
+ fail "inst:$idx"
+ }
+ }
+}