summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2014-12-05 01:51:49 -0800
committerGabe Black <gabeblack@google.com>2014-12-05 01:51:49 -0800
commitf9f46b8fa91e1da166b1e346029f3072a40223c9 (patch)
treeced1905a0d4dc7ec3cf5b9cd5dd75226ccc67473 /src
parentbacbb8ecbcee2b4c5c3fe71f415abc5852ae4a8f (diff)
downloadgem5-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.cc24
-rw-r--r--src/base/remote_gdb.hh15
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;