1761e3c10SMatheus Branco Borellafrom __future__ import print_function 2761e3c10SMatheus Branco Borella# 3*7893e42dSPhilippe Mathieu-Daudé# Test some of the system debug features with the multiarch memory 4761e3c10SMatheus Branco Borella# test. It is a port of the original vmlinux focused test case but 5761e3c10SMatheus Branco Borella# using the "memory" test instead. 6761e3c10SMatheus Branco Borella# 7761e3c10SMatheus Branco Borella# This is launched via tests/guest-debug/run-test.py 8761e3c10SMatheus Branco Borella# 9761e3c10SMatheus Branco Borella 10761e3c10SMatheus Branco Borellaimport gdb 11761e3c10SMatheus Branco Borellaimport sys 12761e3c10SMatheus Branco Borella 13761e3c10SMatheus Branco Borellafailcount = 0 14761e3c10SMatheus Branco Borella 15761e3c10SMatheus Branco Borella 16761e3c10SMatheus Branco Borelladef report(cond, msg): 17761e3c10SMatheus Branco Borella "Report success/fail of test" 18761e3c10SMatheus Branco Borella if cond: 19761e3c10SMatheus Branco Borella print("PASS: %s" % (msg)) 20761e3c10SMatheus Branco Borella else: 21761e3c10SMatheus Branco Borella print("FAIL: %s" % (msg)) 22761e3c10SMatheus Branco Borella global failcount 23761e3c10SMatheus Branco Borella failcount += 1 24761e3c10SMatheus Branco Borella 25761e3c10SMatheus Branco Borella 26761e3c10SMatheus Branco Borelladef check_interrupt(thread): 27761e3c10SMatheus Branco Borella """ 28761e3c10SMatheus Branco Borella Check that, if thread is resumed, we go back to the same thread when the 29761e3c10SMatheus Branco Borella program gets interrupted. 30761e3c10SMatheus Branco Borella """ 31761e3c10SMatheus Branco Borella 32761e3c10SMatheus Branco Borella # Switch to the thread we're going to be running the test in. 33761e3c10SMatheus Branco Borella print("thread ", thread.num) 34761e3c10SMatheus Branco Borella gdb.execute("thr %d" % thread.num) 35761e3c10SMatheus Branco Borella 36761e3c10SMatheus Branco Borella # Enter the loop() function on this thread. 37761e3c10SMatheus Branco Borella # 38761e3c10SMatheus Branco Borella # While there are cleaner ways to do this, we want to minimize the number of 39761e3c10SMatheus Branco Borella # side effects on the gdbstub's internal state, since those may mask bugs. 40761e3c10SMatheus Branco Borella # Ideally, there should be no difference between what we're doing here and 41761e3c10SMatheus Branco Borella # the program reaching the loop() function on its own. 42761e3c10SMatheus Branco Borella # 43761e3c10SMatheus Branco Borella # For this to be safe, we only need the prologue of loop() to not have 44761e3c10SMatheus Branco Borella # instructions that may have problems with what we're doing here. We don't 45761e3c10SMatheus Branco Borella # have to worry about anything else, as this function never returns. 46761e3c10SMatheus Branco Borella gdb.execute("set $pc = loop") 47761e3c10SMatheus Branco Borella 48761e3c10SMatheus Branco Borella # Continue and then interrupt the task. 49761e3c10SMatheus Branco Borella gdb.post_event(lambda: gdb.execute("interrupt")) 50761e3c10SMatheus Branco Borella gdb.execute("c") 51761e3c10SMatheus Branco Borella 52761e3c10SMatheus Branco Borella # Check whether the thread we're in after the interruption is the same we 53761e3c10SMatheus Branco Borella # ran continue from. 54761e3c10SMatheus Branco Borella return (thread.num == gdb.selected_thread().num) 55761e3c10SMatheus Branco Borella 56761e3c10SMatheus Branco Borella 57761e3c10SMatheus Branco Borelladef run_test(): 58761e3c10SMatheus Branco Borella """ 59761e3c10SMatheus Branco Borella Test if interrupting the code always lands us on the same thread when 60761e3c10SMatheus Branco Borella running with scheduler-lock enabled. 61761e3c10SMatheus Branco Borella """ 62761e3c10SMatheus Branco Borella 63761e3c10SMatheus Branco Borella gdb.execute("set scheduler-locking on") 64761e3c10SMatheus Branco Borella for thread in gdb.selected_inferior().threads(): 65761e3c10SMatheus Branco Borella report(check_interrupt(thread), 66761e3c10SMatheus Branco Borella "thread %d resumes correctly on interrupt" % thread.num) 67761e3c10SMatheus Branco Borella 68761e3c10SMatheus Branco Borella 69761e3c10SMatheus Branco Borella# 70761e3c10SMatheus Branco Borella# This runs as the script it sourced (via -x, via run-test.py) 71761e3c10SMatheus Branco Borella# 72761e3c10SMatheus Branco Borellatry: 73761e3c10SMatheus Branco Borella inferior = gdb.selected_inferior() 74761e3c10SMatheus Branco Borella arch = inferior.architecture() 75761e3c10SMatheus Branco Borella print("ATTACHED: %s" % arch.name()) 76761e3c10SMatheus Branco Borellaexcept (gdb.error, AttributeError): 77761e3c10SMatheus Branco Borella print("SKIPPING (not connected)", file=sys.stderr) 78761e3c10SMatheus Branco Borella exit(0) 79761e3c10SMatheus Branco Borella 80761e3c10SMatheus Branco Borellaif gdb.parse_and_eval('$pc') == 0: 81761e3c10SMatheus Branco Borella print("SKIP: PC not set") 82761e3c10SMatheus Branco Borella exit(0) 83761e3c10SMatheus Branco Borellaif len(gdb.selected_inferior().threads()) == 1: 84761e3c10SMatheus Branco Borella print("SKIP: set to run on a single thread") 85761e3c10SMatheus Branco Borella exit(0) 86761e3c10SMatheus Branco Borella 87761e3c10SMatheus Branco Borellatry: 88761e3c10SMatheus Branco Borella # Run the actual tests 89761e3c10SMatheus Branco Borella run_test() 90761e3c10SMatheus Branco Borellaexcept (gdb.error): 91761e3c10SMatheus Branco Borella print("GDB Exception: %s" % (sys.exc_info()[0])) 92761e3c10SMatheus Branco Borella failcount += 1 93761e3c10SMatheus Branco Borella pass 94761e3c10SMatheus Branco Borella 95761e3c10SMatheus Branco Borella# Finally kill the inferior and exit gdb with a count of failures 96761e3c10SMatheus Branco Borellagdb.execute("kill") 97761e3c10SMatheus Branco Borellaexit(failcount) 98