sal: fix watch/breakpoint perf implementation
This commit changes the entities in a ResultSet from listener indexes (into ListenerManagers m_BufferList) to BaseListener pointers, as ListenerManager::makeActive(BaseListener*) (called from FastBreakpoints/Watchpoints.ah) may invalidate indexes temporarily stored in a ResultSet. The issue occurs when multiple breakpoints (watchpoints) fire at the same time, and one added more recently than the others occupies the largest index position in m_BufferList. Although this issue is extremely rare and was only observed in a few corner cases up to now, it may have falsified results in the past. Change-Id: I7b788a06d412f15700ca75f56f2be5d3b78465fa
This commit is contained in:
@ -16,7 +16,7 @@ ResultSet& PerfVectorBreakpoints::gather(BPEvent* pData)
|
||||
// Update trigger IPtr:
|
||||
pLi->setTriggerInstructionPointer(pData->getTriggerInstructionPointer());
|
||||
pLi->setTriggerCPU(pData->getTriggerCPU());
|
||||
res.add(*it);
|
||||
res.add(pLi);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
|
||||
@ -44,14 +44,15 @@ public:
|
||||
* Results (= indices of matching listeners) returned by the "gather"-method,
|
||||
* see below. (This class can be seen as a "temporary fire-list".)
|
||||
*/
|
||||
class BaseListener;
|
||||
class ResultSet {
|
||||
private:
|
||||
std::vector<index_t> m_Res; //!< vector of matching listener indices
|
||||
std::vector<BaseListener *> m_Res; //!< vector of pointers to matching listeners
|
||||
public:
|
||||
ResultSet() { }
|
||||
bool hasMore() const { return !m_Res.empty(); }
|
||||
index_t getNext() { index_t idx = m_Res.back(); m_Res.pop_back(); return idx; }
|
||||
void add(index_t idx) { m_Res.push_back(idx); }
|
||||
BaseListener *getNext() { BaseListener *l = m_Res.back(); m_Res.pop_back(); return l; }
|
||||
void add(BaseListener *l) { m_Res.push_back(l); }
|
||||
size_t size() const { return m_Res.size(); }
|
||||
void clear() { m_Res.clear(); }
|
||||
};
|
||||
|
||||
@ -65,12 +65,12 @@ aspect FastBreakpoints {
|
||||
// Check for matching BPSingleListeners:
|
||||
fail::ResultSet& res1 = ref.getSingleListeners().gather(&tmp);
|
||||
while (res1.hasMore())
|
||||
ref.makeActive(ref.dereference(res1.getNext()));
|
||||
ref.makeActive(res1.getNext());
|
||||
|
||||
// Check for matching BPRangeListeners:
|
||||
fail::ResultSet& res2 = ref.getRangeListeners().gather(&tmp);
|
||||
while (res2.hasMore())
|
||||
ref.makeActive(ref.dereference(res2.getNext()));
|
||||
ref.makeActive(res2.getNext());
|
||||
|
||||
ref.triggerActiveListeners();
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ aspect FastWatchpoints {
|
||||
// Check for matching MemAccessListener:
|
||||
fail::ResultSet& res = ref.getMemoryListeners().gather(&tmp);
|
||||
while (res.hasMore())
|
||||
ref.makeActive(ref.dereference(res.getNext()));
|
||||
ref.makeActive(res.getNext());
|
||||
|
||||
ref.triggerActiveListeners();
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ ResultSet& PerfVectorWatchpoints::gather(MemAccessEvent* pData)
|
||||
pmal->setTriggerWidth(pData->getTriggerWidth());
|
||||
pmal->setTriggerAccessType(pData->getTriggerAccessType());
|
||||
pmal->setTriggerCPU(pData->getTriggerCPU());
|
||||
res.add(*it);
|
||||
res.add(pmal);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
|
||||
Reference in New Issue
Block a user