From f9f46b8fa91e1da166b1e346029f3072a40223c9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 5 Dec 2014 01:51:49 -0800 Subject: 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. --- src/base/remote_gdb.cc | 24 ++++++++++++++++++++---- src/base/remote_gdb.hh | 15 +++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) (limited to 'src/base') 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; -- cgit v1.2.3