1 from __future__
import print_function
3 # Test some of the softmmu debug features with the multiarch memory
4 # test. It is a port of the original vmlinux focused test case but
5 # using the "memory" test instead.
7 # This is launched via tests/guest-debug/run-test.py
16 def report(cond
, msg
):
17 "Report success/fail of test"
19 print("PASS: %s" % (msg
))
21 print("FAIL: %s" % (msg
))
27 "Step an instruction, check it moved."
28 start_pc
= gdb
.parse_and_eval('$pc')
30 end_pc
= gdb
.parse_and_eval('$pc')
32 return not (start_pc
== end_pc
)
36 # Currently it's hard to create a hbreak with the pure python API and
37 # manually matching PC to symbol address is a bit flaky thanks to
38 # function prologues. However internally QEMU's gdbstub treats them
39 # the same as normal breakpoints so it will do for now.
41 def check_break(sym_name
):
42 "Setup breakpoint, continue and check we stopped."
43 sym
, ok
= gdb
.lookup_symbol(sym_name
)
44 bp
= gdb
.Breakpoint(sym_name
, gdb
.BP_BREAKPOINT
)
48 # hopefully we came back
49 end_pc
= gdb
.parse_and_eval('$pc')
50 report(bp
.hit_count
== 1,
51 "break @ %s (%s %d hits)" % (end_pc
, sym
.value(), bp
.hit_count
))
56 def do_one_watch(sym
, wtype
, text
):
58 wp
= gdb
.Breakpoint(sym
, gdb
.BP_WATCHPOINT
, wtype
)
60 report_str
= "%s for %s" % (text
, sym
)
63 report(True, report_str
)
66 report(False, report_str
)
69 def check_watches(sym_name
):
70 "Watch a symbol for any access."
72 # Should hit for any read
73 do_one_watch(sym_name
, gdb
.WP_ACCESS
, "awatch")
75 # Again should hit for reads
76 do_one_watch(sym_name
, gdb
.WP_READ
, "rwatch")
78 # Finally when it is written
79 do_one_watch(sym_name
, gdb
.WP_WRITE
, "watch")
83 "Run through the tests one by one"
85 print("Checking we can step the first few instructions")
91 report(step_ok
== 3, "single step in boot code")
93 # If we get here we have missed some of the other breakpoints.
94 print("Setup catch-all for _exit")
95 cbp
= gdb
.Breakpoint("_exit", gdb
.BP_BREAKPOINT
)
98 check_watches("test_data[128]")
100 report(cbp
.hit_count
== 0, "didn't reach backstop")
103 # This runs as the script it sourced (via -x, via run-test.py)
106 inferior
= gdb
.selected_inferior()
107 arch
= inferior
.architecture()
108 print("ATTACHED: %s" % arch
.name())
109 except (gdb
.error
, AttributeError):
110 print("SKIPPING (not connected)", file=sys
.stderr
)
113 if gdb
.parse_and_eval('$pc') == 0:
114 print("SKIP: PC not set")
118 # These are not very useful in scripts
119 gdb
.execute("set pagination off")
121 # Run the actual tests
124 print("GDB Exception: %s" % (sys
.exc_info()[0]))
128 # Finally kill the inferior and exit gdb with a count of failures