Fix race condition updating local map data.
If the underlying local map changes, it's possible for multiple
threads to try and modify the map data associated with the UnwindLocalMap
object. Add a lock when generating the local map to avoid this problem.
In addition, add a read lock whenever any caller gets the maps iterator.
Updated all iterator callers to make this lock.
Bug: 29387050
Bug: 31067025
(cherry picked from commit 3a14004c7f521cf2ca6dfea182fa7441e77c97e7)
Change-Id: Id00116f156a24b36085c0d5dfc3dde4d2ac55194
diff --git a/include/backtrace/BacktraceMap.h b/include/backtrace/BacktraceMap.h
index 2373c45..b80045f 100644
--- a/include/backtrace/BacktraceMap.h
+++ b/include/backtrace/BacktraceMap.h
@@ -71,6 +71,12 @@
bool IsWritable(uintptr_t pc) { return GetFlags(pc) & PROT_WRITE; }
bool IsExecutable(uintptr_t pc) { return GetFlags(pc) & PROT_EXEC; }
+ // In order to use the iterators on this object, a caller must
+ // call the LockIterator and UnlockIterator function to guarantee
+ // that the data does not change while it's being used.
+ virtual void LockIterator() {}
+ virtual void UnlockIterator() {}
+
typedef std::deque<backtrace_map_t>::iterator iterator;
iterator begin() { return maps_.begin(); }
iterator end() { return maps_.end(); }
@@ -102,4 +108,18 @@
pid_t pid_;
};
+class ScopedBacktraceMapIteratorLock {
+public:
+ explicit ScopedBacktraceMapIteratorLock(BacktraceMap* map) : map_(map) {
+ map->LockIterator();
+ }
+
+ ~ScopedBacktraceMapIteratorLock() {
+ map_->UnlockIterator();
+ }
+
+private:
+ BacktraceMap* map_;
+};
+
#endif // _BACKTRACE_BACKTRACE_MAP_H