diff options
author | Tim Newsome <tim@sifive.com> | 2023-07-06 14:41:39 -0700 |
---|---|---|
committer | Tim Newsome <tim@sifive.com> | 2023-07-17 09:35:00 -0700 |
commit | 995fa259b95f5c1b77fe768a00a7d444162fb36f (patch) | |
tree | 77a1adf25d658c0eb242fc30a4fe6ac77c7b7675 | |
parent | ba831d02bdb4249ef744bd04da6c912680c7b66e (diff) | |
download | riscv-tests-995fa259b95f5c1b77fe768a00a7d444162fb36f.zip riscv-tests-995fa259b95f5c1b77fe768a00a7d444162fb36f.tar.gz riscv-tests-995fa259b95f5c1b77fe768a00a7d444162fb36f.tar.bz2 |
debug: CeaseRunTest -> UnavailableRunTest
Use new spike mechanism to test OpenOCD behavior when the current hart
becomes unavailable while running.
Create ThreadTerminated exception.
-rwxr-xr-x | debug/gdbserver.py | 21 | ||||
-rw-r--r-- | debug/testlib.py | 5 |
2 files changed, 23 insertions, 3 deletions
diff --git a/debug/gdbserver.py b/debug/gdbserver.py index bf04f2e..ad85e34 100755 --- a/debug/gdbserver.py +++ b/debug/gdbserver.py @@ -20,6 +20,7 @@ from testlib import GdbTest, GdbSingleHartTest, TestFailed from testlib import TestNotApplicable, CompileError from testlib import UnknownThread from testlib import CouldNotReadRegisters, CommandException +from testlib import ThreadTerminated MSTATUS_UIE = 0x00000001 MSTATUS_SIE = 0x00000002 @@ -1879,11 +1880,12 @@ class CeaseStepiTest(ProgramTest): except CouldNotReadRegisters: pass -class CeaseRunTest(ProgramTest): +class UnavailableRunTest(ProgramTest): """Test that we work correctly when the hart we're debugging ceases to respond.""" def early_applicable(self): - return self.hart.support_cease + return self.hart.support_cease or \ + self.target.support_unavailable_control def test(self): self.gdb.b("main") @@ -1891,10 +1893,23 @@ class CeaseRunTest(ProgramTest): assertIn("Breakpoint", output) assertIn("main", output) - self.gdb.p("$pc=precease") + if self.target.support_unavailable_control: + self.gdb.p("$pc=loop_forever") + else: + self.gdb.p("$pc=cease") self.gdb.c(wait=False) + if self.target.support_unavailable_control: + self.server.wait_until_running([self.hart]) + self.server.command( + f"riscv dmi_write 0x1f 0x{(~(1<<self.hart.id))&0x3:x}") self.gdb.expect(r"\S+ became unavailable.") self.gdb.interrupt() + # gdb might automatically switch to the available hart. + try: + self.gdb.select_hart(self.hart) + except ThreadTerminated: + # GDB sees that the thread is gone. Count this as success. + return try: self.gdb.p("$pc") assert False, ("Registers shouldn't be accessible when the hart is " diff --git a/debug/testlib.py b/debug/testlib.py index fd9882a..63cc49c 100644 --- a/debug/testlib.py +++ b/debug/testlib.py @@ -555,6 +555,9 @@ class UnknownThread(Exception): def __init__(self, explanation): Exception.__init__(self, explanation) +class ThreadTerminated(Exception): + pass + Thread = collections.namedtuple('Thread', ('id', 'description', 'target_id', 'name', 'frame')) @@ -762,6 +765,8 @@ class Gdb: output = self.command(f"thread {h['thread'].id}", ops=5) if "Unknown" in output: raise UnknownThread(output) + if f"Thread ID {h['thread'].id} has terminated" in output: + raise ThreadTerminated(output) def push_state(self): self.stack.append({ |