diff options
author | Tom de Vries <tdevries@suse.de> | 2020-12-04 13:36:47 +0100 |
---|---|---|
committer | Tom de Vries <tdevries@suse.de> | 2020-12-04 13:36:47 +0100 |
commit | 9c027c2f6c5cdb3db0b8c72c06b691c5ba502279 (patch) | |
tree | d185e8438ffe0a6ffc0ff28551e33249cc02c4cc /gdb | |
parent | c524d11e50729ac1a14ac1e749d9a5c459881391 (diff) | |
download | gdb-9c027c2f6c5cdb3db0b8c72c06b691c5ba502279.zip gdb-9c027c2f6c5cdb3db0b8c72c06b691c5ba502279.tar.gz gdb-9c027c2f6c5cdb3db0b8c72c06b691c5ba502279.tar.bz2 |
[gdb/testsuite] Handle SIGILL in gdb.reverse/insn-reverse.exp
Consider test-case gdb.reverse/insn-reverse.exp.
It runs a number of subtests, dependent on the architecture, f.i. for
x86_64 it runs subtests rdrand and rdseed.
For each subtest, it checks whether the subtest is supported and otherwise
bails out of that subtest.
However, there may be a problem with the support test or the information it
relies on, and if it states that a subtest is supported while it is actually
not, we may run into a SIGILL, as f.i. described in PR21166, which results in
tcl errors like this:
...
ERROR: tcl error sourcing src/gdb/testsuite/gdb.reverse/insn-reverse.exp.
ERROR: can't read "insn_array(5)": no such element in array
...
We can emulate this by inserting a sigfpe in function rdrand in
insn-reverse-x86.c, like this:
...
volatile int a = 0; volatile int b = 1; volatile int c = b / a;
...
The problem is that the loop in the test-case attempts to stepi over of all
insn in rdrand, but because of the signal it will never get to the last insn.
Handle this by detecting that the stepi made no progress, and bailing out of
the loop.
Furthermore, make running of the subtests independent, such that a SIGILL in
subtest rdrand does not affect running of subtest rdseed.
Tested on x86_64-linux.
gdb/testsuite/ChangeLog:
2020-12-04 Tom de Vries <tdevries@suse.de>
* gdb.reverse/insn-reverse.c (test_nr): New var.
(usage, parse_args): New function.
(main): Call parse_args. Only run test for test_nr.
* gdb.reverse/insn-reverse.exp: Detect lack of progress in stepi loop
and bail out. Run subtests individually, using an inferior arg
specifying the subtest.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/testsuite/ChangeLog | 9 | ||||
-rw-r--r-- | gdb/testsuite/gdb.reverse/insn-reverse.c | 43 | ||||
-rw-r--r-- | gdb/testsuite/gdb.reverse/insn-reverse.exp | 15 |
3 files changed, 61 insertions, 6 deletions
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index c00bc61..36953af 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2020-12-04 Tom de Vries <tdevries@suse.de> + + * gdb.reverse/insn-reverse.c (test_nr): New var. + (usage, parse_args): New function. + (main): Call parse_args. Only run test for test_nr. + * gdb.reverse/insn-reverse.exp: Detect lack of progress in stepi loop + and bail out. Run subtests individually, using an inferior arg + specifying the subtest. + 2020-12-02 Andrew Burgess <andrew.burgess@embecosm.com> * gdb.arch/riscv-tdesc-regs.exp: Remove unwanted test. diff --git a/gdb/testsuite/gdb.reverse/insn-reverse.c b/gdb/testsuite/gdb.reverse/insn-reverse.c index 08d382d..b3881d4 100644 --- a/gdb/testsuite/gdb.reverse/insn-reverse.c +++ b/gdb/testsuite/gdb.reverse/insn-reverse.c @@ -15,6 +15,9 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <stdlib.h> +#include <stdio.h> + typedef void (*testcase_ftype) (void); /* The arch-specific files need to implement both the initialize function @@ -45,16 +48,48 @@ initialize (void) array is defined together with them. */ static int n_testcases = (sizeof (testcases) / sizeof (testcase_ftype)); +static void +usage (void) +{ + printf ("usage: insn-reverse <0-%d>\n", n_testcases - 1); +} + +static int test_nr; + +static void +parse_args (int argc, char **argv) +{ + if (argc != 2) + { + usage (); + exit (1); + } + + char *tail; + test_nr = strtol (argv[1], &tail, 10); + if (*tail != '\0') + { + usage (); + exit (1); + } + + int in_range_p = 0 <= test_nr && test_nr < n_testcases; + if (!in_range_p) + { + usage (); + exit (1); + } +} + int -main () +main (int argc, char **argv) { - int i = 0; + parse_args (argc, argv); /* Initialize any required arch-specific bits. */ initialize (); - for (i = 0; i < n_testcases; i++) - testcases[i] (); + testcases[test_nr] (); return 0; } diff --git a/gdb/testsuite/gdb.reverse/insn-reverse.exp b/gdb/testsuite/gdb.reverse/insn-reverse.exp index 174b795..d60f873 100644 --- a/gdb/testsuite/gdb.reverse/insn-reverse.exp +++ b/gdb/testsuite/gdb.reverse/insn-reverse.exp @@ -50,11 +50,14 @@ proc read_testcase { n } { # the contents of registers are saved, and test compares them. If # there is any differences, a FAIL is emitted. -proc test { func } { +proc test { func testcase_nr } { global hex decimal global gdb_prompt with_test_prefix "$func" { + gdb_start_cmd $testcase_nr + gdb_test "" "" "wait for prompt" + gdb_breakpoint $func gdb_test "continue" @@ -74,15 +77,23 @@ proc test { func } { # Registers contents before each forward single step. set count 0 + set insn_addr "" for {} {$count < 500} {incr count} { gdb_test_multiple "x/i \$pc" "" { -re ".* ($hex) <.*>:\[ \t\]*(.*)\r\n$gdb_prompt $" { + set prev_insn_addr $insn_addr set insn_addr $expect_out(1,string) if [expr {$last_insn == $insn_addr}] { break } + if { $prev_insn_addr == $insn_addr } { + # Failed to make progress, might have run into SIGILL. + unsupported "no progress at: $expect_out(2,string)" + break + } + set insn_array($count) $expect_out(2,string) } } @@ -125,5 +136,5 @@ if { ${n_testcases} == 0 } { for { set i 0 } { ${i} < ${n_testcases} } { incr i } { set testcase [read_testcase $i] - test $testcase + test $testcase $i } |