fastmodel: Use a shared pointer to track PC events.

When the last event is removed from a breakpoint, then the breakpoint
itself is uninstalled from IRIS, and the list is deleted. Even though
the list has been traversed and so we don't lose track of any other
events that need to be processed, we also still need to check against
end() to see that we're done. If that now freed memory gets
overwritten, then we won't see the end and will wander right off the
end of the list into nonsense.

This change modifies the breakpoint info tracking structure to keep a
shared pointer to the event list. The pointer will still automatically
manage the list's memory so that it doesn't leak, and it won't get
deleted out from under us as we're iterating through it.

Change-Id: I5ad0f095d07f0a3a5cce9c10f03121827a674c33
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/24965
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Chun-Chen TK Hsu <chunchenhsu@google.com>
This commit is contained in:
Gabe Black
2020-02-01 02:21:15 -08:00
parent 11e57de23a
commit 5100b81d1c
2 changed files with 11 additions and 7 deletions

View File

@@ -228,8 +228,9 @@ ThreadContext::breakpointHit(
auto it = getOrAllocBp(pc);
auto e_it = it->second->events.begin();
while (e_it != it->second->events.end()) {
std::shared_ptr<BpInfo::EventList> events = it->second->events;
auto e_it = events->begin();
while (e_it != events->end()) {
PCEvent *e = *e_it;
// Advance e_it here since e might remove itself from the list.
e_it++;
@@ -319,7 +320,7 @@ bool
ThreadContext::schedule(PCEvent *e)
{
auto it = getOrAllocBp(e->pc());
it->second->events.push_back(e);
it->second->events->push_back(e);
if (_instId != iris::IRIS_UINT64_MAX && !it->second->validId())
installBp(it);
@@ -331,7 +332,7 @@ bool
ThreadContext::remove(PCEvent *e)
{
auto it = getOrAllocBp(e->pc());
it->second->events.remove(e);
it->second->events->remove(e);
if (it->second->empty())
delBp(it);

View File

@@ -110,11 +110,14 @@ class ThreadContext : public ::ThreadContext
{
Addr pc;
BpId id;
std::list<PCEvent *> events;
using EventList = std::list<PCEvent *>;
std::shared_ptr<EventList> events;
BpInfo(Addr _pc) : pc(_pc), id(iris::IRIS_UINT64_MAX) {}
BpInfo(Addr _pc) : pc(_pc), id(iris::IRIS_UINT64_MAX),
events(new EventList)
{}
bool empty() const { return events.empty(); }
bool empty() const { return events->empty(); }
bool validId() const { return id != iris::IRIS_UINT64_MAX; }
void clearId() { id = iris::IRIS_UINT64_MAX; }
};