1from __future__ import print_function 2# 3# Test some of the system 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. 6# 7# This is launched via tests/guest-debug/run-test.py 8# 9 10import gdb 11import sys 12from test_gdbstub import main, report 13 14 15def check_step(): 16 "Step an instruction, check it moved." 17 start_pc = gdb.parse_and_eval('$pc') 18 gdb.execute("si") 19 end_pc = gdb.parse_and_eval('$pc') 20 21 return not (start_pc == end_pc) 22 23 24# 25# Currently it's hard to create a hbreak with the pure python API and 26# manually matching PC to symbol address is a bit flaky thanks to 27# function prologues. However internally QEMU's gdbstub treats them 28# the same as normal breakpoints so it will do for now. 29# 30def check_break(sym_name): 31 "Setup breakpoint, continue and check we stopped." 32 sym, ok = gdb.lookup_symbol(sym_name) 33 bp = gdb.Breakpoint(sym_name, gdb.BP_BREAKPOINT) 34 35 gdb.execute("c") 36 37 # hopefully we came back 38 end_pc = gdb.parse_and_eval('$pc') 39 report(bp.hit_count == 1, 40 "break @ %s (%s %d hits)" % (end_pc, sym.value(), bp.hit_count)) 41 42 bp.delete() 43 44 45def do_one_watch(sym, wtype, text): 46 47 wp = gdb.Breakpoint(sym, gdb.BP_WATCHPOINT, wtype) 48 gdb.execute("c") 49 report_str = "%s for %s" % (text, sym) 50 51 if wp.hit_count > 0: 52 report(True, report_str) 53 wp.delete() 54 else: 55 report(False, report_str) 56 57 58def check_watches(sym_name): 59 "Watch a symbol for any access." 60 61 # Should hit for any read 62 do_one_watch(sym_name, gdb.WP_ACCESS, "awatch") 63 64 # Again should hit for reads 65 do_one_watch(sym_name, gdb.WP_READ, "rwatch") 66 67 # Finally when it is written 68 do_one_watch(sym_name, gdb.WP_WRITE, "watch") 69 70 71def run_test(): 72 "Run through the tests one by one" 73 74 print("Checking we can step the first few instructions") 75 step_ok = 0 76 for i in range(3): 77 if check_step(): 78 step_ok += 1 79 80 report(step_ok == 3, "single step in boot code") 81 82 # If we get here we have missed some of the other breakpoints. 83 print("Setup catch-all for _exit") 84 cbp = gdb.Breakpoint("_exit", gdb.BP_BREAKPOINT) 85 86 check_break("main") 87 check_watches("test_data[128]") 88 89 report(cbp.hit_count == 0, "didn't reach backstop") 90 91 92main(run_test) 93