From d1d8863086c57f04236418f21ef8a7fbfc184b0b Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Sat, 19 Mar 2016 13:33:58 -0700 Subject: [PATCH] Add --gdb-port It's necessary to be able to run multiple spikes at once on the same box. --- riscv/gdbserver.cc | 44 ++++++++++++++++++++++---------------------- riscv/gdbserver.h | 2 +- riscv/sim.cc | 2 +- spike_main/spike.cc | 14 ++++++++++---- tests/gdbserver.py | 8 ++++---- tests/testlib.py | 16 ++++++++++++++-- 6 files changed, 52 insertions(+), 34 deletions(-) diff --git a/riscv/gdbserver.cc b/riscv/gdbserver.cc index 0b36421..0ab1aef 100644 --- a/riscv/gdbserver.cc +++ b/riscv/gdbserver.cc @@ -700,30 +700,30 @@ void gdbserver_t::handle_interrupt() void gdbserver_t::handle() { - processor_t *p = sim->get_core(0); - if (running && p->halted) { - // The core was running, but now it's halted. Better tell gdb. - switch (p->halt_reason) { - case HR_NONE: - fprintf(stderr, "Internal error. Processor halted without reason.\n"); - abort(); - case HR_STEPPED: - case HR_INTERRUPT: - case HR_CMDLINE: - case HR_ATTACHED: - // There's no gdb code for this. - send_packet("T05"); - break; - case HR_SWBP: - send_packet("T05swbreak:;"); - break; + if (client_fd > 0) { + processor_t *p = sim->get_core(0); + if (running && p->halted) { + // The core was running, but now it's halted. Better tell gdb. + switch (p->halt_reason) { + case HR_NONE: + fprintf(stderr, "Internal error. Processor halted without reason.\n"); + abort(); + case HR_STEPPED: + case HR_INTERRUPT: + case HR_CMDLINE: + case HR_ATTACHED: + // There's no gdb code for this. + send_packet("T05"); + break; + case HR_SWBP: + send_packet("T05swbreak:;"); + break; + } + send_packet("T00"); + // TODO: Actually include register values here + running = false; } - send_packet("T00"); - // TODO: Actually include register values here - running = false; - } - if (client_fd > 0) { this->read(); this->write(); diff --git a/riscv/gdbserver.h b/riscv/gdbserver.h index 8a7111f..0c92372 100644 --- a/riscv/gdbserver.h +++ b/riscv/gdbserver.h @@ -13,7 +13,7 @@ public: circular_buffer_t(unsigned int capacity) : data(new T[capacity]), start(0), end(0), capacity(capacity) {} circular_buffer_t() : start(0), end(0), capacity(0) {} - ~circular_buffer_t() { delete data; } + ~circular_buffer_t() { delete[] data; } T *data; unsigned int start; // Data start, inclusive. diff --git a/riscv/sim.cc b/riscv/sim.cc index 19d3d84..ccaa6c8 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -23,7 +23,7 @@ static void handle_signal(int sig) sim_t::sim_t(const char* isa, size_t nprocs, size_t mem_mb, bool halted, const std::vector& args) : htif(new htif_isasim_t(this, args)), procs(std::max(nprocs, size_t(1))), - current_step(0), current_proc(0), debug(false) + current_step(0), current_proc(0), debug(false), gdbserver(NULL) { signal(SIGINT, &handle_signal); // allocate target machine's memory, shrinking it as necessary diff --git a/spike_main/spike.cc b/spike_main/spike.cc index 8896bc7..f63f14f 100644 --- a/spike_main/spike.cc +++ b/spike_main/spike.cc @@ -31,6 +31,7 @@ static void help() fprintf(stderr, " --l2=:: B both powers of 2).\n"); fprintf(stderr, " --extension= Specify RoCC Extension\n"); fprintf(stderr, " --extlib= Shared library to load\n"); + fprintf(stderr, " --gdb-port= Listen on for gdb to connect\n"); fprintf(stderr, " --dump-config-string Print platform configuration string and exit\n"); exit(1); } @@ -49,6 +50,7 @@ int main(int argc, char** argv) std::unique_ptr l2; std::function extension; const char* isa = DEFAULT_ISA; + uint16_t gdb_port = 0; option_parser_t parser; parser.help(&help); @@ -58,6 +60,9 @@ int main(int argc, char** argv) parser.option('l', 0, 0, [&](const char* s){log = true;}); parser.option('p', 0, 1, [&](const char* s){nprocs = atoi(s);}); parser.option('m', 0, 1, [&](const char* s){mem_mb = atoi(s);}); + // I wanted to use --halted, but for some reason that doesn't work. + parser.option('H', 0, 0, [&](const char* s){halted = true;}); + parser.option(0, "gdb-port", 1, [&](const char* s){gdb_port = atoi(s);}); parser.option(0, "ic", 1, [&](const char* s){ic.reset(new icache_sim_t(s));}); parser.option(0, "dc", 1, [&](const char* s){dc.reset(new dcache_sim_t(s));}); parser.option(0, "l2", 1, [&](const char* s){l2.reset(cache_sim_t::construct(s, "L2$"));}); @@ -71,14 +76,15 @@ int main(int argc, char** argv) exit(-1); } }); - // I wanted to use --halted, but for some reason that doesn't work. - parser.option('H', 0, 0, [&](const char* s){halted = true;}); auto argv1 = parser.parse(argv); std::vector htif_args(argv1, (const char*const*)argv + argc); sim_t s(isa, nprocs, mem_mb, halted, htif_args); - gdbserver_t gdbserver(9824, &s); - s.set_gdbserver(&gdbserver); + std::unique_ptr gdbserver; + if (gdb_port) { + gdbserver = std::unique_ptr(new gdbserver_t(gdb_port, &s)); + s.set_gdbserver(&(*gdbserver)); + } if (dump_config_string) { printf("%s", s.get_config_string()); diff --git a/tests/gdbserver.py b/tests/gdbserver.py index b5363e6..90ebbe9 100755 --- a/tests/gdbserver.py +++ b/tests/gdbserver.py @@ -9,10 +9,10 @@ import time class DebugTest(unittest.TestCase): def setUp(self): self.binary = testlib.compile("debug.c") - self.spike = testlib.spike(self.binary, halted=False) + self.spike, self.port = testlib.spike(self.binary, halted=False) self.gdb = testlib.Gdb() self.gdb.command("file %s" % self.binary) - self.gdb.command("target extended-remote localhost:9824") + self.gdb.command("target extended-remote localhost:%d" % self.port) self.gdb.command("p i=0"); def tearDown(self): @@ -68,10 +68,10 @@ class DebugTest(unittest.TestCase): class RegsTest(unittest.TestCase): def setUp(self): self.binary = testlib.compile("regs.s") - self.spike = testlib.spike(self.binary, halted=False) + self.spike, self.port = testlib.spike(self.binary, halted=False) self.gdb = testlib.Gdb() self.gdb.command("file %s" % self.binary) - self.gdb.command("target extended-remote localhost:9824") + self.gdb.command("target extended-remote localhost:%d" % self.port) def tearDown(self): self.spike.kill() diff --git a/tests/testlib.py b/tests/testlib.py index 2590f46..2db2549 100644 --- a/tests/testlib.py +++ b/tests/testlib.py @@ -25,13 +25,25 @@ def compile(src): assert result == 0, "%r failed" % cmd return dst +def unused_port(): + # http://stackoverflow.com/questions/2838244/get-open-tcp-port-in-python/2838309#2838309 + import socket + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.bind(("",0)) + port = s.getsockname()[1] + s.close() + return port + def spike(binary, halted=False): + """Launch spike. Return tuple of its process and the port it's running on.""" cmd = [find_file("spike")] if halted: cmd.append('-H') - cmd += ['pk', binary] + port = unused_port() + cmd += ['--gdb-port', str(port), 'pk', binary] logfile = open("spike.log", "w") - return subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=logfile, stderr=logfile) + return subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=logfile, + stderr=logfile), port class Gdb(object): def __init__(self): -- 2.30.2