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();
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.
sim_t::sim_t(const char* isa, size_t nprocs, size_t mem_mb, bool halted,
const std::vector<std::string>& 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
fprintf(stderr, " --l2=<S>:<W>:<B> B both powers of 2).\n");
fprintf(stderr, " --extension=<name> Specify RoCC Extension\n");
fprintf(stderr, " --extlib=<name> Shared library to load\n");
+ fprintf(stderr, " --gdb-port=<port> Listen on <port> for gdb to connect\n");
fprintf(stderr, " --dump-config-string Print platform configuration string and exit\n");
exit(1);
}
std::unique_ptr<cache_sim_t> l2;
std::function<extension_t*()> extension;
const char* isa = DEFAULT_ISA;
+ uint16_t gdb_port = 0;
option_parser_t parser;
parser.help(&help);
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$"));});
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<std::string> 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_t> gdbserver;
+ if (gdb_port) {
+ gdbserver = std::unique_ptr<gdbserver_t>(new gdbserver_t(gdb_port, &s));
+ s.set_gdbserver(&(*gdbserver));
+ }
if (dump_config_string) {
printf("%s", s.get_config_string());
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):
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()
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):