diff options
author | Toshihito Kikuchi <k.toshihito@yahoo.de> | 2016-06-09 22:47:42 -0700 |
---|---|---|
committer | Toshihito Kikuchi <k.toshihito@yahoo.de> | 2016-06-09 22:50:47 -0700 |
commit | bb556f1facb86cdd1591d490f2d2d670bdd5a1ee (patch) | |
tree | ccc99d237487ee5952ff66d92a4f2a207dd41f6a /gdb/testsuite | |
parent | c040f3fb55315f06ceb9e6de6ac167a95a445ace (diff) | |
download | gdb-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/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/examine-backward.c | 106 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/examine-backward.exp | 324 |
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" + } + } +} |