Commit 3acbe29b by Abseil Team Committed by Copybara-Service

Enable ABSL_BTREE_ENABLE_GENERATIONS and ABSL_SWISSTABLE_ENABLE_GENERATIONS with…

Enable ABSL_BTREE_ENABLE_GENERATIONS and ABSL_SWISSTABLE_ENABLE_GENERATIONS with ABSL_HAVE_HWADDRESS_SANITIZER.

It will detect bugs similar to Asan.

Also updated related tests to pass with HWASAN.
They are still flaky because of nature of HWASAN algorithm,
but test can be update to avoid flakiness, which I will do
in followup patches.

PiperOrigin-RevId: 597613798
Change-Id: Ic8af36a268ca041c002eb561b946aa2d9b93996a
parent a00f6d6d
...@@ -1346,7 +1346,8 @@ void ExpectOperationCounts(const int expected_moves, ...@@ -1346,7 +1346,8 @@ void ExpectOperationCounts(const int expected_moves,
tracker->ResetCopiesMovesSwaps(); tracker->ResetCopiesMovesSwaps();
} }
#ifdef ABSL_HAVE_ADDRESS_SANITIZER #if defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
defined(ABSL_HAVE_HWADDRESS_SANITIZER)
constexpr bool kAsan = true; constexpr bool kAsan = true;
#else #else
constexpr bool kAsan = false; constexpr bool kAsan = false;
...@@ -3079,10 +3080,10 @@ TEST(Btree, InvalidIteratorUse) { ...@@ -3079,10 +3080,10 @@ TEST(Btree, InvalidIteratorUse) {
if (!BtreeGenerationsEnabled()) if (!BtreeGenerationsEnabled())
GTEST_SKIP() << "Generation validation for iterators is disabled."; GTEST_SKIP() << "Generation validation for iterators is disabled.";
// Invalid memory use can trigger heap-use-after-free in ASan or invalidated // Invalid memory use can trigger use-after-free in ASan, HWASAN or
// iterator assertions. // invalidated iterator assertions.
constexpr const char *kInvalidMemoryDeathMessage = constexpr const char *kInvalidMemoryDeathMessage =
"heap-use-after-free|invalidated iterator"; "use-after-free|invalidated iterator";
{ {
absl::btree_set<int> set; absl::btree_set<int> set;
...@@ -3411,12 +3412,12 @@ TEST(Btree, InvalidPointerUse) { ...@@ -3411,12 +3412,12 @@ TEST(Btree, InvalidPointerUse) {
set.insert(0); set.insert(0);
const int *ptr = &*set.begin(); const int *ptr = &*set.begin();
set.insert(1); set.insert(1);
EXPECT_DEATH(std::cout << *ptr, "heap-use-after-free"); EXPECT_DEATH(std::cout << *ptr, "use-after-free");
size_t slots_per_node = BtreeNodePeer::GetNumSlotsPerNode<decltype(set)>(); size_t slots_per_node = BtreeNodePeer::GetNumSlotsPerNode<decltype(set)>();
for (int i = 2; i < slots_per_node - 1; ++i) set.insert(i); for (int i = 2; i < slots_per_node - 1; ++i) set.insert(i);
ptr = &*set.begin(); ptr = &*set.begin();
set.insert(static_cast<int>(slots_per_node)); set.insert(static_cast<int>(slots_per_node));
EXPECT_DEATH(std::cout << *ptr, "heap-use-after-free"); EXPECT_DEATH(std::cout << *ptr, "use-after-free");
} }
template<typename Set> template<typename Set>
......
...@@ -79,6 +79,7 @@ namespace container_internal { ...@@ -79,6 +79,7 @@ namespace container_internal {
#ifdef ABSL_BTREE_ENABLE_GENERATIONS #ifdef ABSL_BTREE_ENABLE_GENERATIONS
#error ABSL_BTREE_ENABLE_GENERATIONS cannot be directly set #error ABSL_BTREE_ENABLE_GENERATIONS cannot be directly set
#elif defined(ABSL_HAVE_ADDRESS_SANITIZER) || \ #elif defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
defined(ABSL_HAVE_HWADDRESS_SANITIZER) || \
defined(ABSL_HAVE_MEMORY_SANITIZER) defined(ABSL_HAVE_MEMORY_SANITIZER)
// When compiled in sanitizer mode, we add generation integers to the nodes and // When compiled in sanitizer mode, we add generation integers to the nodes and
// iterators. When iterators are used, we validate that the container has not // iterators. When iterators are used, we validate that the container has not
...@@ -2856,7 +2857,8 @@ inline auto btree<P>::internal_emplace(iterator iter, Args &&...args) ...@@ -2856,7 +2857,8 @@ inline auto btree<P>::internal_emplace(iterator iter, Args &&...args)
} }
} }
(void)replaced_node; (void)replaced_node;
#ifdef ABSL_HAVE_ADDRESS_SANITIZER #if defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
defined(ABSL_HAVE_HWADDRESS_SANITIZER)
if (!replaced_node) { if (!replaced_node) {
assert(iter.node_->is_leaf()); assert(iter.node_->is_leaf());
if (iter.node_->is_root()) { if (iter.node_->is_root()) {
......
...@@ -234,6 +234,7 @@ namespace container_internal { ...@@ -234,6 +234,7 @@ namespace container_internal {
#ifdef ABSL_SWISSTABLE_ENABLE_GENERATIONS #ifdef ABSL_SWISSTABLE_ENABLE_GENERATIONS
#error ABSL_SWISSTABLE_ENABLE_GENERATIONS cannot be directly set #error ABSL_SWISSTABLE_ENABLE_GENERATIONS cannot be directly set
#elif defined(ABSL_HAVE_ADDRESS_SANITIZER) || \ #elif defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
defined(ABSL_HAVE_HWADDRESS_SANITIZER) || \
defined(ABSL_HAVE_MEMORY_SANITIZER) defined(ABSL_HAVE_MEMORY_SANITIZER)
// When compiled in sanitizer mode, we add generation integers to the backing // When compiled in sanitizer mode, we add generation integers to the backing
// array and iterators. In the backing array, we store the generation between // array and iterators. In the backing array, we store the generation between
......
...@@ -2218,10 +2218,10 @@ TEST(TableDeathTest, InvalidIteratorAsserts) { ...@@ -2218,10 +2218,10 @@ TEST(TableDeathTest, InvalidIteratorAsserts) {
EXPECT_DEATH_IF_SUPPORTED(++iter, kErasedDeathMessage); EXPECT_DEATH_IF_SUPPORTED(++iter, kErasedDeathMessage);
} }
// Invalid iterator use can trigger heap-use-after-free in asan, // Invalid iterator use can trigger use-after-free in asan/hwasan,
// use-of-uninitialized-value in msan, or invalidated iterator assertions. // use-of-uninitialized-value in msan, or invalidated iterator assertions.
constexpr const char* kInvalidIteratorDeathMessage = constexpr const char* kInvalidIteratorDeathMessage =
"heap-use-after-free|use-of-uninitialized-value|invalidated " "use-after-free|use-of-uninitialized-value|invalidated "
"iterator|Invalid iterator|invalid iterator"; "iterator|Invalid iterator|invalid iterator";
// MSVC doesn't support | in regex. // MSVC doesn't support | in regex.
...@@ -2579,7 +2579,7 @@ TEST(Table, InvalidReferenceUseCrashesWithSanitizers) { ...@@ -2579,7 +2579,7 @@ TEST(Table, InvalidReferenceUseCrashesWithSanitizers) {
// ptr will become invalidated on rehash. // ptr will become invalidated on rehash.
const int64_t* ptr = &*t.begin(); const int64_t* ptr = &*t.begin();
t.insert(++i); t.insert(++i);
EXPECT_DEATH_IF_SUPPORTED(std::cout << *ptr, "heap-use-after-free") << i; EXPECT_DEATH_IF_SUPPORTED(std::cout << *ptr, "use-after-free") << i;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment