fastmodel: Use a shared pointer to track PC events.
authorGabe Black <gabeblack@google.com>
Sat, 1 Feb 2020 10:21:15 +0000 (02:21 -0800)
committerGabe Black <gabeblack@google.com>
Thu, 20 Feb 2020 10:20:45 +0000 (10:20 +0000)
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>
src/arch/arm/fastmodel/iris/thread_context.cc
src/arch/arm/fastmodel/iris/thread_context.hh

index 260e5a845b00f9a1508f842c92af8a23d41e14f7..547a4c47ff3382127679dfddc54646327c316bd1 100644 (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);
index 0b55415325c472d9baf285203b4382fcad1932ca..89b0004b4679457f6c38913459711c1eeb31357f 100644 (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; }
     };