]>
Commit | Line | Data |
---|---|---|
db2ea0dd AB |
1 | #!/usr/bin/env python3 |
2 | # | |
3 | # Run a gdbstub test case | |
4 | # | |
5 | # Copyright (c) 2019 Linaro | |
6 | # | |
7 | # Author: Alex Bennée <[email protected]> | |
8 | # | |
9 | # This work is licensed under the terms of the GNU GPL, version 2 or later. | |
10 | # See the COPYING file in the top-level directory. | |
11 | # | |
12 | # SPDX-License-Identifier: GPL-2.0-or-later | |
13 | ||
14 | import argparse | |
15 | import subprocess | |
16 | import shutil | |
17 | import shlex | |
b0dc2a8b AB |
18 | import os |
19 | from tempfile import TemporaryDirectory | |
db2ea0dd AB |
20 | |
21 | def get_args(): | |
22 | parser = argparse.ArgumentParser(description="A gdbstub test runner") | |
23 | parser.add_argument("--qemu", help="Qemu binary for test", | |
24 | required=True) | |
25 | parser.add_argument("--qargs", help="Qemu arguments for test") | |
26 | parser.add_argument("--binary", help="Binary to debug", | |
27 | required=True) | |
28 | parser.add_argument("--test", help="GDB test script", | |
29 | required=True) | |
30 | parser.add_argument("--gdb", help="The gdb binary to use", default=None) | |
31 | ||
32 | return parser.parse_args() | |
33 | ||
34 | if __name__ == '__main__': | |
35 | args = get_args() | |
36 | ||
37 | # Search for a gdb we can use | |
38 | if not args.gdb: | |
39 | args.gdb = shutil.which("gdb-multiarch") | |
40 | if not args.gdb: | |
41 | args.gdb = shutil.which("gdb") | |
42 | if not args.gdb: | |
43 | print("We need gdb to run the test") | |
44 | exit(-1) | |
45 | ||
b0dc2a8b AB |
46 | socket_dir = TemporaryDirectory("qemu-gdbstub") |
47 | socket_name = os.path.join(socket_dir.name, "gdbstub.socket") | |
48 | ||
db2ea0dd AB |
49 | # Launch QEMU with binary |
50 | if "system" in args.qemu: | |
51 | cmd = "%s %s %s -s -S" % (args.qemu, args.qargs, args.binary) | |
52 | else: | |
b0dc2a8b AB |
53 | cmd = "%s %s -g %s %s" % (args.qemu, args.qargs, socket_name, |
54 | args.binary) | |
db2ea0dd AB |
55 | |
56 | inferior = subprocess.Popen(shlex.split(cmd)) | |
57 | ||
58 | # Now launch gdb with our test and collect the result | |
d2fefded AB |
59 | gdb_cmd = "%s %s" % (args.gdb, args.binary) |
60 | # run quietly and ignore .gdbinit | |
61 | gdb_cmd += " -q -n -batch" | |
62 | # disable prompts in case of crash | |
63 | gdb_cmd += " -ex 'set confirm off'" | |
64 | # connect to remote | |
b0dc2a8b AB |
65 | if "system" in args.qemu: |
66 | gdb_cmd += " -ex 'target remote localhost:1234'" | |
67 | else: | |
68 | gdb_cmd += " -ex 'target remote %s'" % (socket_name) | |
d2fefded AB |
69 | # finally the test script itself |
70 | gdb_cmd += " -x %s" % (args.test) | |
71 | ||
72 | print("GDB CMD: %s" % (gdb_cmd)) | |
db2ea0dd AB |
73 | |
74 | result = subprocess.call(gdb_cmd, shell=True); | |
75 | ||
d2fefded AB |
76 | # A negative result is the result of an internal gdb failure like |
77 | # a crash. We force a return of 0 so we don't fail the test on | |
78 | # account of broken external tools. | |
79 | if result < 0: | |
80 | print("GDB crashed? SKIPPING") | |
81 | exit(0) | |
82 | ||
b03e4fff AB |
83 | try: |
84 | inferior.wait(2) | |
85 | except subprocess.TimeoutExpired: | |
86 | print("GDB never connected? Killed guest") | |
87 | inferior.kill() | |
88 | ||
db2ea0dd | 89 | exit(result) |