-
Type: Bug
-
Resolution: Fixed
-
Priority: Major - P3
-
Affects Version/s: None
-
Component/s: None
-
Fully Compatible
-
ALL
-
v5.0
-
-
Service Arch 2021-06-14
In ConnectionPool::dropConnections here, we used a range-based for loop to iterate through the ConnectionPool's _pools member, a. stdx::unordered_map. Within the loop, we call ConnectionPool::SpecificPool::triggerShutdown on each specific pool we find in the _pools map. This member function will erase this specific pool from the parent ConnectionPool's _pools member here.
According to the std::unordered_map documentation for the "erase" overload set, "References and iterators to the erased elements are invalidated. Other iterators and references are not invalidated." While the abseil documentation is a bit unclear, I think the same applies for the absl::node_hash_map we're actually using (and, in any case, we should probably live by the standard library documentation for stdx:: types). This means that once the specific pool element is erased in triggerShutdown, any iterators to it are invalidated – which implies when that when the ranged-based for loop attempts to advance to the next element in the map by calling next() on the iterator, it will be using/dereferencing an invalid iterator.
Our current version of abseil seems to leave this iterator in a valid state long enough for the for-loop to advance, but this is not guaranteed: when we attempted an upgrade to the newest version of abseil (see SERVER-51476), in at least one test we see that we fail an internal assert inside abseil when attempting to advance the iterator in this range-based for loop, suggesting that the iterator the loop is attempting to advance is invalid.
- is depended on by
-
SERVER-51476 Upgrade Abseil to 20210324.1
- Closed