diff options
author | Gabe Black <gabeblack@google.com> | 2014-12-05 01:51:49 -0800 |
---|---|---|
committer | Gabe Black <gabeblack@google.com> | 2014-12-05 01:51:49 -0800 |
commit | f9f46b8fa91e1da166b1e346029f3072a40223c9 (patch) | |
tree | ced1905a0d4dc7ec3cf5b9cd5dd75226ccc67473 /src | |
parent | bacbb8ecbcee2b4c5c3fe71f415abc5852ae4a8f (diff) | |
download | gem5-f9f46b8fa91e1da166b1e346029f3072a40223c9.tar.xz |
sim: Ensure GDB interrupts the simulation at an instruction boundary.
Use the comInstEventQueue to ensure GDB interrupts the simulation at an
instruction boundary and not in the middle of a macroop, memory access, etc.
Diffstat (limited to 'src')
-rw-r--r-- | src/base/remote_gdb.cc | 24 | ||||
-rw-r--r-- | src/base/remote_gdb.hh | 15 |
2 files changed, 35 insertions, 4 deletions
diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc index 42b94b5f9..7143763dd 100644 --- a/src/base/remote_gdb.cc +++ b/src/base/remote_gdb.cc @@ -1,4 +1,5 @@ /* + * Copyright 2014 Google, Inc. * Copyright (c) 2002-2005 The Regents of The University of Michigan * All rights reserved. * @@ -129,6 +130,7 @@ #include "base/socket.hh" #include "base/trace.hh" #include "config/the_isa.hh" +#include "cpu/base.hh" #include "cpu/static_inst.hh" #include "cpu/thread_context.hh" #include "debug/GDBAll.hh" @@ -246,14 +248,28 @@ BaseRemoteGDB::Event::Event(BaseRemoteGDB *g, int fd, int e) void BaseRemoteGDB::Event::process(int revent) { - if (revent & POLLIN) - gdb->trap(SIGILL); - else if (revent & POLLNVAL) + BaseCPU *cpu = gdb->context->getCpuPtr(); + EventQueue *eq = cpu->comInstEventQueue[gdb->context->threadId()]; + if (revent & POLLIN) { + gdb->trapEvent.type(SIGILL); + // Here "ticks" aren't simulator ticks which measure time, they're + // instructions committed by the CPU. + eq->schedule(&gdb->trapEvent, eq->getCurTick()); + } else if (revent & POLLNVAL) { + if (gdb->trapEvent.scheduled()) + eq->deschedule(&gdb->trapEvent); gdb->detach(); + } +} + +void +BaseRemoteGDB::TrapEvent::process() +{ + gdb->trap(_type); } BaseRemoteGDB::BaseRemoteGDB(System *_system, ThreadContext *c, size_t cacheSize) - : event(NULL), listener(NULL), number(-1), fd(-1), + : event(NULL), trapEvent(this), listener(NULL), number(-1), fd(-1), active(false), attached(false), system(_system), context(c), gdbregs(cacheSize) diff --git a/src/base/remote_gdb.hh b/src/base/remote_gdb.hh index ef414f09b..110059141 100644 --- a/src/base/remote_gdb.hh +++ b/src/base/remote_gdb.hh @@ -115,8 +115,23 @@ class BaseRemoteGDB void process(int revent); }; + class TrapEvent : public ::Event + { + protected: + int _type; + BaseRemoteGDB *gdb; + + public: + TrapEvent(BaseRemoteGDB *g) : gdb(g) + {} + + void type(int t) { _type = t; } + void process(); + }; + friend class Event; Event *event; + TrapEvent trapEvent; GDBListener *listener; int number; |