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