tests/tcg: Factor out gdbstub test functions
Both the report() function as well as the initial gdbstub test sequence are copy-pasted into ~10 files with slight modifications. This indicates that they are indeed generic, so factor them out. While at it, add a few newlines to make the formatting closer to PEP-8. Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> Message-Id: <20240129093410.3151-3-iii@linux.ibm.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
87ab270429
commit
4d48c1bc07
@ -97,7 +97,12 @@ if __name__ == '__main__':
|
||||
sleep(1)
|
||||
log(output, "GDB CMD: %s" % (gdb_cmd))
|
||||
|
||||
result = subprocess.call(gdb_cmd, shell=True, stdout=output, stderr=stderr)
|
||||
gdb_env = dict(os.environ)
|
||||
gdb_pythonpath = gdb_env.get("PYTHONPATH", "").split(os.pathsep)
|
||||
gdb_pythonpath.append(os.path.dirname(os.path.realpath(__file__)))
|
||||
gdb_env["PYTHONPATH"] = os.pathsep.join(gdb_pythonpath)
|
||||
result = subprocess.call(gdb_cmd, shell=True, stdout=output, stderr=stderr,
|
||||
env=gdb_env)
|
||||
|
||||
# A result of greater than 128 indicates a fatal signal (likely a
|
||||
# crash due to gdb internal failure). That's a problem for GDB and
|
||||
|
60
tests/guest-debug/test_gdbstub.py
Normal file
60
tests/guest-debug/test_gdbstub.py
Normal file
@ -0,0 +1,60 @@
|
||||
"""Helper functions for gdbstub testing
|
||||
|
||||
"""
|
||||
from __future__ import print_function
|
||||
import gdb
|
||||
import os
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
fail_count = 0
|
||||
|
||||
|
||||
def report(cond, msg):
|
||||
"""Report success/fail of a test"""
|
||||
if cond:
|
||||
print("PASS: {}".format(msg))
|
||||
else:
|
||||
print("FAIL: {}".format(msg))
|
||||
global fail_count
|
||||
fail_count += 1
|
||||
|
||||
|
||||
def main(test, expected_arch=None):
|
||||
"""Run a test function
|
||||
|
||||
This runs as the script it sourced (via -x, via run-test.py)."""
|
||||
try:
|
||||
inferior = gdb.selected_inferior()
|
||||
arch = inferior.architecture()
|
||||
print("ATTACHED: {}".format(arch.name()))
|
||||
if expected_arch is not None:
|
||||
report(arch.name() == expected_arch,
|
||||
"connected to {}".format(expected_arch))
|
||||
except (gdb.error, AttributeError):
|
||||
print("SKIP: not connected")
|
||||
exit(0)
|
||||
|
||||
if gdb.parse_and_eval("$pc") == 0:
|
||||
print("SKIP: PC not set")
|
||||
exit(0)
|
||||
|
||||
try:
|
||||
test()
|
||||
except:
|
||||
print("GDB Exception:")
|
||||
traceback.print_exc(file=sys.stdout)
|
||||
global fail_count
|
||||
fail_count += 1
|
||||
if "QEMU_TEST_INTERACTIVE" in os.environ:
|
||||
import code
|
||||
code.InteractiveConsole(locals=globals()).interact()
|
||||
raise
|
||||
|
||||
try:
|
||||
gdb.execute("kill")
|
||||
except gdb.error:
|
||||
pass
|
||||
|
||||
print("All tests complete: {} failures".format(fail_count))
|
||||
exit(fail_count)
|
@ -8,19 +8,10 @@ from __future__ import print_function
|
||||
#
|
||||
|
||||
import gdb
|
||||
import sys
|
||||
from test_gdbstub import main, report
|
||||
|
||||
initial_vlen = 0
|
||||
failcount = 0
|
||||
|
||||
def report(cond, msg):
|
||||
"Report success/fail of test"
|
||||
if cond:
|
||||
print ("PASS: %s" % (msg))
|
||||
else:
|
||||
print ("FAIL: %s" % (msg))
|
||||
global failcount
|
||||
failcount += 1
|
||||
|
||||
class TestBreakpoint(gdb.Breakpoint):
|
||||
def __init__(self, sym_name="__sve_ld_done"):
|
||||
@ -64,26 +55,5 @@ def run_test():
|
||||
|
||||
gdb.execute("c")
|
||||
|
||||
#
|
||||
# This runs as the script it sourced (via -x, via run-test.py)
|
||||
#
|
||||
try:
|
||||
inferior = gdb.selected_inferior()
|
||||
arch = inferior.architecture()
|
||||
report(arch.name() == "aarch64", "connected to aarch64")
|
||||
except (gdb.error, AttributeError):
|
||||
print("SKIPPING (not connected)", file=sys.stderr)
|
||||
exit(0)
|
||||
|
||||
try:
|
||||
# Run the actual tests
|
||||
run_test()
|
||||
except:
|
||||
print ("GDB Exception: %s" % (sys.exc_info()[0]))
|
||||
failcount += 1
|
||||
import code
|
||||
code.InteractiveConsole(locals=globals()).interact()
|
||||
raise
|
||||
|
||||
print("All tests complete: %d failures" % failcount)
|
||||
exit(failcount)
|
||||
main(run_test, expected_arch="aarch64")
|
||||
|
@ -6,20 +6,10 @@ from __future__ import print_function
|
||||
#
|
||||
|
||||
import gdb
|
||||
import sys
|
||||
from test_gdbstub import main, report
|
||||
|
||||
MAGIC = 0xDEADBEEF
|
||||
|
||||
failcount = 0
|
||||
|
||||
def report(cond, msg):
|
||||
"Report success/fail of test"
|
||||
if cond:
|
||||
print ("PASS: %s" % (msg))
|
||||
else:
|
||||
print ("FAIL: %s" % (msg))
|
||||
global failcount
|
||||
failcount += 1
|
||||
|
||||
def run_test():
|
||||
"Run through the tests one by one"
|
||||
@ -54,24 +44,5 @@ def run_test():
|
||||
report(str(v.type) == "uint64_t", "size of %s" % (reg))
|
||||
report(int(v) == MAGIC, "%s is 0x%x" % (reg, MAGIC))
|
||||
|
||||
#
|
||||
# This runs as the script it sourced (via -x, via run-test.py)
|
||||
#
|
||||
try:
|
||||
inferior = gdb.selected_inferior()
|
||||
arch = inferior.architecture()
|
||||
report(arch.name() == "aarch64", "connected to aarch64")
|
||||
except (gdb.error, AttributeError):
|
||||
print("SKIPPING (not connected)", file=sys.stderr)
|
||||
exit(0)
|
||||
|
||||
try:
|
||||
# Run the actual tests
|
||||
run_test()
|
||||
except:
|
||||
print ("GDB Exception: %s" % (sys.exc_info()[0]))
|
||||
failcount += 1
|
||||
|
||||
print("All tests complete: %d failures" % failcount)
|
||||
|
||||
exit(failcount)
|
||||
main(run_test, expected_arch="aarch64")
|
||||
|
@ -8,19 +8,7 @@ from __future__ import print_function
|
||||
#
|
||||
|
||||
import gdb
|
||||
import sys
|
||||
|
||||
failcount = 0
|
||||
|
||||
|
||||
def report(cond, msg):
|
||||
"Report success/fail of test"
|
||||
if cond:
|
||||
print("PASS: %s" % (msg))
|
||||
else:
|
||||
print("FAIL: %s" % (msg))
|
||||
global failcount
|
||||
failcount += 1
|
||||
from test_gdbstub import main, report
|
||||
|
||||
|
||||
def check_interrupt(thread):
|
||||
@ -59,6 +47,9 @@ def run_test():
|
||||
Test if interrupting the code always lands us on the same thread when
|
||||
running with scheduler-lock enabled.
|
||||
"""
|
||||
if len(gdb.selected_inferior().threads()) == 1:
|
||||
print("SKIP: set to run on a single thread")
|
||||
exit(0)
|
||||
|
||||
gdb.execute("set scheduler-locking on")
|
||||
for thread in gdb.selected_inferior().threads():
|
||||
@ -66,32 +57,4 @@ def run_test():
|
||||
"thread %d resumes correctly on interrupt" % thread.num)
|
||||
|
||||
|
||||
#
|
||||
# This runs as the script it sourced (via -x, via run-test.py)
|
||||
#
|
||||
try:
|
||||
inferior = gdb.selected_inferior()
|
||||
arch = inferior.architecture()
|
||||
print("ATTACHED: %s" % arch.name())
|
||||
except (gdb.error, AttributeError):
|
||||
print("SKIPPING (not connected)", file=sys.stderr)
|
||||
exit(0)
|
||||
|
||||
if gdb.parse_and_eval('$pc') == 0:
|
||||
print("SKIP: PC not set")
|
||||
exit(0)
|
||||
if len(gdb.selected_inferior().threads()) == 1:
|
||||
print("SKIP: set to run on a single thread")
|
||||
exit(0)
|
||||
|
||||
try:
|
||||
# Run the actual tests
|
||||
run_test()
|
||||
except (gdb.error):
|
||||
print("GDB Exception: %s" % (sys.exc_info()[0]))
|
||||
failcount += 1
|
||||
pass
|
||||
|
||||
# Finally kill the inferior and exit gdb with a count of failures
|
||||
gdb.execute("kill")
|
||||
exit(failcount)
|
||||
main(run_test)
|
||||
|
@ -9,18 +9,7 @@ from __future__ import print_function
|
||||
|
||||
import gdb
|
||||
import sys
|
||||
|
||||
failcount = 0
|
||||
|
||||
|
||||
def report(cond, msg):
|
||||
"Report success/fail of test"
|
||||
if cond:
|
||||
print("PASS: %s" % (msg))
|
||||
else:
|
||||
print("FAIL: %s" % (msg))
|
||||
global failcount
|
||||
failcount += 1
|
||||
from test_gdbstub import main, report
|
||||
|
||||
|
||||
def check_step():
|
||||
@ -99,29 +88,5 @@ def run_test():
|
||||
|
||||
report(cbp.hit_count == 0, "didn't reach backstop")
|
||||
|
||||
#
|
||||
# This runs as the script it sourced (via -x, via run-test.py)
|
||||
#
|
||||
try:
|
||||
inferior = gdb.selected_inferior()
|
||||
arch = inferior.architecture()
|
||||
print("ATTACHED: %s" % arch.name())
|
||||
except (gdb.error, AttributeError):
|
||||
print("SKIPPING (not connected)", file=sys.stderr)
|
||||
exit(0)
|
||||
|
||||
if gdb.parse_and_eval('$pc') == 0:
|
||||
print("SKIP: PC not set")
|
||||
exit(0)
|
||||
|
||||
try:
|
||||
# Run the actual tests
|
||||
run_test()
|
||||
except (gdb.error):
|
||||
print("GDB Exception: %s" % (sys.exc_info()[0]))
|
||||
failcount += 1
|
||||
pass
|
||||
|
||||
# Finally kill the inferior and exit gdb with a count of failures
|
||||
gdb.execute("kill")
|
||||
exit(failcount)
|
||||
main(run_test)
|
||||
|
@ -7,20 +7,11 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import gdb
|
||||
import sys
|
||||
import xml.etree.ElementTree as ET
|
||||
from test_gdbstub import main, report
|
||||
|
||||
|
||||
initial_vlen = 0
|
||||
failcount = 0
|
||||
|
||||
def report(cond, msg):
|
||||
"Report success/fail of test."
|
||||
if cond:
|
||||
print("PASS: %s" % (msg))
|
||||
else:
|
||||
print("FAIL: %s" % (msg))
|
||||
global failcount
|
||||
failcount += 1
|
||||
|
||||
|
||||
def fetch_xml_regmap():
|
||||
@ -75,6 +66,7 @@ def fetch_xml_regmap():
|
||||
|
||||
return reg_map
|
||||
|
||||
|
||||
def get_register_by_regnum(reg_map, regnum):
|
||||
"""
|
||||
Helper to find a register from the map via its XML regnum
|
||||
@ -84,6 +76,7 @@ def get_register_by_regnum(reg_map, regnum):
|
||||
return entry
|
||||
return None
|
||||
|
||||
|
||||
def crosscheck_remote_xml(reg_map):
|
||||
"""
|
||||
Cross-check the list of remote-registers with the XML info.
|
||||
@ -144,6 +137,7 @@ def crosscheck_remote_xml(reg_map):
|
||||
elif "seen" not in x_reg:
|
||||
print(f"{x_reg} wasn't seen in remote-registers")
|
||||
|
||||
|
||||
def initial_register_read(reg_map):
|
||||
"""
|
||||
Do an initial read of all registers that we know gdb cares about
|
||||
@ -214,27 +208,4 @@ def run_test():
|
||||
complete_and_diff(reg_map)
|
||||
|
||||
|
||||
#
|
||||
# This runs as the script it sourced (via -x, via run-test.py)
|
||||
#
|
||||
try:
|
||||
inferior = gdb.selected_inferior()
|
||||
arch = inferior.architecture()
|
||||
print("ATTACHED: %s" % arch.name())
|
||||
except (gdb.error, AttributeError):
|
||||
print("SKIPPING (not connected)", file=sys.stderr)
|
||||
exit(0)
|
||||
|
||||
if gdb.parse_and_eval('$pc') == 0:
|
||||
print("SKIP: PC not set")
|
||||
exit(0)
|
||||
|
||||
try:
|
||||
run_test()
|
||||
except (gdb.error):
|
||||
print ("GDB Exception: %s" % (sys.exc_info()[0]))
|
||||
failcount += 1
|
||||
pass
|
||||
|
||||
print("All tests complete: %d failures" % failcount)
|
||||
exit(failcount)
|
||||
main(run_test)
|
||||
|
@ -7,19 +7,11 @@ from __future__ import print_function
|
||||
#
|
||||
|
||||
import gdb
|
||||
import sys
|
||||
from test_gdbstub import main, report
|
||||
|
||||
|
||||
initial_vlen = 0
|
||||
failcount = 0
|
||||
|
||||
def report(cond, msg):
|
||||
"Report success/fail of test"
|
||||
if cond:
|
||||
print("PASS: %s" % (msg))
|
||||
else:
|
||||
print("FAIL: %s" % (msg))
|
||||
global failcount
|
||||
failcount += 1
|
||||
|
||||
def check_break(sym_name):
|
||||
"Setup breakpoint, continue and check we stopped."
|
||||
@ -35,6 +27,7 @@ def check_break(sym_name):
|
||||
|
||||
bp.delete()
|
||||
|
||||
|
||||
def run_test():
|
||||
"Run through the tests one by one"
|
||||
|
||||
@ -57,28 +50,5 @@ def run_test():
|
||||
# finally check we don't barf inspecting registers
|
||||
gdb.execute("info registers")
|
||||
|
||||
#
|
||||
# This runs as the script it sourced (via -x, via run-test.py)
|
||||
#
|
||||
try:
|
||||
inferior = gdb.selected_inferior()
|
||||
arch = inferior.architecture()
|
||||
print("ATTACHED: %s" % arch.name())
|
||||
except (gdb.error, AttributeError):
|
||||
print("SKIPPING (not connected)", file=sys.stderr)
|
||||
exit(0)
|
||||
|
||||
if gdb.parse_and_eval('$pc') == 0:
|
||||
print("SKIP: PC not set")
|
||||
exit(0)
|
||||
|
||||
try:
|
||||
# Run the actual tests
|
||||
run_test()
|
||||
except (gdb.error):
|
||||
print ("GDB Exception: %s" % (sys.exc_info()[0]))
|
||||
failcount += 1
|
||||
pass
|
||||
|
||||
print("All tests complete: %d failures" % failcount)
|
||||
exit(failcount)
|
||||
main(run_test)
|
||||
|
@ -3,20 +3,7 @@
|
||||
This runs as a sourced script (via -x, via run-test.py)."""
|
||||
from __future__ import print_function
|
||||
import gdb
|
||||
import sys
|
||||
|
||||
|
||||
n_failures = 0
|
||||
|
||||
|
||||
def report(cond, msg):
|
||||
"""Report success/fail of a test"""
|
||||
if cond:
|
||||
print("PASS: {}".format(msg))
|
||||
else:
|
||||
print("FAIL: {}".format(msg))
|
||||
global n_failures
|
||||
n_failures += 1
|
||||
from test_gdbstub import main, report
|
||||
|
||||
|
||||
def run_test():
|
||||
@ -37,26 +24,4 @@ def run_test():
|
||||
# report("/sha1" in mappings, "Found the test binary name in the mappings")
|
||||
|
||||
|
||||
def main():
|
||||
"""Prepare the environment and run through the tests"""
|
||||
try:
|
||||
inferior = gdb.selected_inferior()
|
||||
print("ATTACHED: {}".format(inferior.architecture().name()))
|
||||
except (gdb.error, AttributeError):
|
||||
print("SKIPPING (not connected)")
|
||||
exit(0)
|
||||
|
||||
if gdb.parse_and_eval('$pc') == 0:
|
||||
print("SKIP: PC not set")
|
||||
exit(0)
|
||||
|
||||
try:
|
||||
# Run the actual tests
|
||||
run_test()
|
||||
except gdb.error:
|
||||
report(False, "GDB Exception: {}".format(sys.exc_info()[0]))
|
||||
print("All tests complete: %d failures" % n_failures)
|
||||
exit(n_failures)
|
||||
|
||||
|
||||
main()
|
||||
main(run_test)
|
||||
|
@ -6,18 +6,8 @@ from __future__ import print_function
|
||||
#
|
||||
|
||||
import gdb
|
||||
import sys
|
||||
from test_gdbstub import main, report
|
||||
|
||||
failcount = 0
|
||||
|
||||
def report(cond, msg):
|
||||
"Report success/fail of test"
|
||||
if cond:
|
||||
print ("PASS: %s" % (msg))
|
||||
else:
|
||||
print ("FAIL: %s" % (msg))
|
||||
global failcount
|
||||
failcount += 1
|
||||
|
||||
def run_test():
|
||||
"Run through the tests one by one"
|
||||
@ -26,28 +16,5 @@ def run_test():
|
||||
report(isinstance(auxv, str), "Fetched auxv from inferior")
|
||||
report(auxv.find("sha1"), "Found test binary name in auxv")
|
||||
|
||||
#
|
||||
# This runs as the script it sourced (via -x, via run-test.py)
|
||||
#
|
||||
try:
|
||||
inferior = gdb.selected_inferior()
|
||||
arch = inferior.architecture()
|
||||
print("ATTACHED: %s" % arch.name())
|
||||
except (gdb.error, AttributeError):
|
||||
print("SKIPPING (not connected)", file=sys.stderr)
|
||||
exit(0)
|
||||
|
||||
if gdb.parse_and_eval('$pc') == 0:
|
||||
print("SKIP: PC not set")
|
||||
exit(0)
|
||||
|
||||
try:
|
||||
# Run the actual tests
|
||||
run_test()
|
||||
except (gdb.error):
|
||||
print ("GDB Exception: %s" % (sys.exc_info()[0]))
|
||||
failcount += 1
|
||||
pass
|
||||
|
||||
print("All tests complete: %d failures" % failcount)
|
||||
exit(failcount)
|
||||
main(run_test)
|
||||
|
@ -6,18 +6,8 @@ from __future__ import print_function
|
||||
#
|
||||
|
||||
import gdb
|
||||
import sys
|
||||
from test_gdbstub import main, report
|
||||
|
||||
failcount = 0
|
||||
|
||||
def report(cond, msg):
|
||||
"Report success/fail of test"
|
||||
if cond:
|
||||
print ("PASS: %s" % (msg))
|
||||
else:
|
||||
print ("FAIL: %s" % (msg))
|
||||
global failcount
|
||||
failcount += 1
|
||||
|
||||
def run_test():
|
||||
"Run through the tests one by one"
|
||||
@ -29,28 +19,5 @@ def run_test():
|
||||
frame = gdb.selected_frame()
|
||||
report(str(frame.function()) == "thread1_func", "break @ %s"%frame)
|
||||
|
||||
#
|
||||
# This runs as the script it sourced (via -x, via run-test.py)
|
||||
#
|
||||
try:
|
||||
inferior = gdb.selected_inferior()
|
||||
arch = inferior.architecture()
|
||||
print("ATTACHED: %s" % arch.name())
|
||||
except (gdb.error, AttributeError):
|
||||
print("SKIPPING (not connected)", file=sys.stderr)
|
||||
exit(0)
|
||||
|
||||
if gdb.parse_and_eval('$pc') == 0:
|
||||
print("SKIP: PC not set")
|
||||
exit(0)
|
||||
|
||||
try:
|
||||
# Run the actual tests
|
||||
run_test()
|
||||
except (gdb.error):
|
||||
print ("GDB Exception: %s" % (sys.exc_info()[0]))
|
||||
failcount += 1
|
||||
pass
|
||||
|
||||
print("All tests complete: %d failures" % failcount)
|
||||
exit(failcount)
|
||||
main(run_test)
|
||||
|
@ -7,19 +7,7 @@ from __future__ import print_function
|
||||
#
|
||||
|
||||
import gdb
|
||||
import sys
|
||||
|
||||
failcount = 0
|
||||
|
||||
|
||||
def report(cond, msg):
|
||||
"""Report success/fail of test"""
|
||||
if cond:
|
||||
print("PASS: %s" % (msg))
|
||||
else:
|
||||
print("FAIL: %s" % (msg))
|
||||
global failcount
|
||||
failcount += 1
|
||||
from test_gdbstub import main, report
|
||||
|
||||
|
||||
def run_test():
|
||||
@ -42,31 +30,7 @@ def run_test():
|
||||
gdb.Breakpoint("_exit")
|
||||
gdb.execute("c")
|
||||
status = int(gdb.parse_and_eval("$r2"))
|
||||
report(status == 0, "status == 0");
|
||||
report(status == 0, "status == 0")
|
||||
|
||||
|
||||
#
|
||||
# This runs as the script it sourced (via -x, via run-test.py)
|
||||
#
|
||||
try:
|
||||
inferior = gdb.selected_inferior()
|
||||
arch = inferior.architecture()
|
||||
print("ATTACHED: %s" % arch.name())
|
||||
except (gdb.error, AttributeError):
|
||||
print("SKIPPING (not connected)", file=sys.stderr)
|
||||
exit(0)
|
||||
|
||||
if gdb.parse_and_eval("$pc") == 0:
|
||||
print("SKIP: PC not set")
|
||||
exit(0)
|
||||
|
||||
try:
|
||||
# Run the actual tests
|
||||
run_test()
|
||||
except (gdb.error):
|
||||
print("GDB Exception: %s" % (sys.exc_info()[0]))
|
||||
failcount += 1
|
||||
pass
|
||||
|
||||
print("All tests complete: %d failures" % failcount)
|
||||
exit(failcount)
|
||||
main(run_test)
|
||||
|
@ -3,20 +3,7 @@
|
||||
This runs as a sourced script (via -x, via run-test.py)."""
|
||||
from __future__ import print_function
|
||||
import gdb
|
||||
import sys
|
||||
|
||||
|
||||
n_failures = 0
|
||||
|
||||
|
||||
def report(cond, msg):
|
||||
"""Report success/fail of a test"""
|
||||
if cond:
|
||||
print("PASS: {}".format(msg))
|
||||
else:
|
||||
print("FAIL: {}".format(msg))
|
||||
global n_failures
|
||||
n_failures += 1
|
||||
from test_gdbstub import main, report
|
||||
|
||||
|
||||
def run_test():
|
||||
@ -35,26 +22,4 @@ def run_test():
|
||||
gdb.execute("si")
|
||||
|
||||
|
||||
def main():
|
||||
"""Prepare the environment and run through the tests"""
|
||||
try:
|
||||
inferior = gdb.selected_inferior()
|
||||
print("ATTACHED: {}".format(inferior.architecture().name()))
|
||||
except (gdb.error, AttributeError):
|
||||
print("SKIPPING (not connected)")
|
||||
exit(0)
|
||||
|
||||
if gdb.parse_and_eval('$pc') == 0:
|
||||
print("SKIP: PC not set")
|
||||
exit(0)
|
||||
|
||||
try:
|
||||
# Run the actual tests
|
||||
run_test()
|
||||
except gdb.error:
|
||||
report(False, "GDB Exception: {}".format(sys.exc_info()[0]))
|
||||
print("All tests complete: %d failures" % n_failures)
|
||||
exit(n_failures)
|
||||
|
||||
|
||||
main()
|
||||
main(run_test)
|
||||
|
Loading…
x
Reference in New Issue
Block a user