Halt when gdb user hits ^C.
authorTim Newsome <tim@sifive.com>
Fri, 6 May 2016 00:40:02 +0000 (17:40 -0700)
committerTim Newsome <tim@sifive.com>
Mon, 23 May 2016 19:12:12 +0000 (12:12 -0700)
riscv/gdbserver.cc
riscv/processor.cc
tests/gdbserver.py
tests/testlib.py

index fbe0027a23a76bfc88f04e41868a9496aef35fa2..f3be2722b4d5b7133a8f8e674a553b075bfc0bb6 100644 (file)
@@ -309,8 +309,11 @@ class halt_op_t : public operation_t
                 fprintf(stderr, "Internal error. Processor halted without reason.\n");
                 abort();
 
-              case DCSR_CAUSE_HWBP:
               case DCSR_CAUSE_DEBUGINT:
+                gs.send_packet("S02");   // Pretend program received SIGINT.
+                break;
+
+              case DCSR_CAUSE_HWBP:
               case DCSR_CAUSE_STEP:
               case DCSR_CAUSE_HALT:
                 // There's no gdb code for this.
@@ -1513,9 +1516,7 @@ void gdbserver_t::handle_packet(const std::vector<uint8_t> &packet)
 void gdbserver_t::handle_interrupt()
 {
   processor_t *p = sim->get_core(0);
-  // TODO p->set_halted(true, HR_INTERRUPT);
-  send_packet("S02");   // Pretend program received SIGINT.
-  // TODO running = false;
+  add_operation(new halt_op_t(*this, true));
 }
 
 void gdbserver_t::handle()
index 4c4e3dd110ee5f352895e7ee34667e5b9c3765c4..d43defc81c48d468303085f5ce118ab206880160 100644 (file)
@@ -279,7 +279,6 @@ static bool validate_vm(int max_xlen, reg_t vm)
 
 void processor_t::set_csr(int which, reg_t val)
 {
-  fprintf(stderr, "set_csr(0x%x, 0x%lx)\n", which, val);
   val = zext_xlen(val);
   reg_t delegable_ints = MIP_SSIP | MIP_STIP | MIP_SEIP | (1 << IRQ_COP);
   reg_t all_ints = delegable_ints | MIP_MSIP | MIP_MTIP;
index ac191d5cd2bfdf6c841e2ad225f6e322df64ac72..297960604e0d9578f06d3265ca771e9db36044d6 100755 (executable)
@@ -13,7 +13,6 @@ class DebugTest(unittest.TestCase):
         self.gdb = testlib.Gdb()
         self.gdb.command("file %s" % self.binary)
         self.gdb.command("target extended-remote localhost:%d" % self.port)
-        self.gdb.command("p i=0");
 
     def tearDown(self):
         self.spike.kill()
@@ -21,6 +20,7 @@ class DebugTest(unittest.TestCase):
 
     def test_turbostep(self):
         """Single step a bunch of times."""
+        self.gdb.command("p i=0");
         last_pc = None
         for _ in range(100):
             self.gdb.command("stepi")
@@ -29,11 +29,13 @@ class DebugTest(unittest.TestCase):
             last_pc = pc
 
     def test_exit(self):
+        self.gdb.command("p i=0");
         output = self.gdb.command("c")
         self.assertIn("Continuing", output)
         self.assertIn("Remote connection closed", output)
 
     def test_breakpoint(self):
+        self.gdb.command("p i=0");
         self.gdb.command("b print_row")
         # The breakpoint should be hit exactly 10 times.
         for i in range(10):
@@ -46,6 +48,7 @@ class DebugTest(unittest.TestCase):
         self.assertIn("Remote connection closed", output)
 
     def test_registers(self):
+        self.gdb.command("p i=0");
         # Try both forms to test gdb.
         for cmd in ("info all-registers", "info registers all"):
             output = self.gdb.command(cmd)
@@ -66,6 +69,20 @@ class DebugTest(unittest.TestCase):
             last_instret = instret
             self.gdb.command("stepi")
 
+    def test_interrupt(self):
+        """Sending gdb ^C while the program is running should cause it to halt."""
+        self.gdb.c(wait=False)
+        time.sleep(0.1)
+        self.gdb.interrupt()
+        self.gdb.command("p i=123");
+        self.gdb.c(wait=False)
+        time.sleep(0.1)
+        self.gdb.interrupt()
+        self.gdb.command("p i=0");
+        output = self.gdb.c()
+        self.assertIn("Continuing", output)
+        self.assertIn("Remote connection closed", output)
+
 class RegsTest(unittest.TestCase):
     def setUp(self):
         self.binary = testlib.compile("regs.s")
index 4e05616390c83e47d43e7b22f461d77c0063e60b..62339016674167c6494d2187649d00650057d781 100644 (file)
@@ -74,6 +74,17 @@ class Gdb(object):
         self.child.expect("\(gdb\)")
         return self.child.before.strip()
 
+    def c(self, wait=True):
+        if wait:
+            return self.command("c")
+        else:
+            self.child.sendline("c")
+            self.child.expect("Continuing")
+
+    def interrupt(self):
+        self.child.send("\003");
+        self.child.expect("\(gdb\)")
+
     def x(self, address, size='w'):
         output = self.command("x/%s %s" % (size, address))
         value = int(output.split(':')[1].strip(), 0)