[asan] Only suggest increasing poison_history_size if the buffer is full (#195732)
I unlikely but possible to setup shadow state, e.g unpoison heap red
zone just after partial granule.
If buffer is not full, increasing it will not help.
diff --git a/compiler-rt/lib/asan/asan_errors.cpp b/compiler-rt/lib/asan/asan_errors.cpp
index 802c838e..cf52cd5 100644
--- a/compiler-rt/lib/asan/asan_errors.cpp
+++ b/compiler-rt/lib/asan/asan_errors.cpp
@@ -662,14 +662,18 @@
}
PoisonRecord record;
- if (FindPoisonRecord(addr, record)) {
+ bool is_full = false;
+ if (FindPoisonRecord(addr, record, is_full)) {
Printf("Memory was manually poisoned by thread T%u:\n", record.thread_id);
StackTrace poison_stack = StackDepotGet(record.stack_id);
if (poison_stack.size > 0)
poison_stack.Print();
} else {
Printf("NOTE: no matching poison tracking record found.\n");
- Printf("Try a larger value for ASAN_OPTIONS=poison_history_size=<size>.\n");
+ if (is_full) {
+ Printf(
+ "Try a larger value for ASAN_OPTIONS=poison_history_size=<size>.\n");
+ }
}
}
diff --git a/compiler-rt/lib/asan/asan_poisoning.cpp b/compiler-rt/lib/asan/asan_poisoning.cpp
index 1da1673..7cdb871 100644
--- a/compiler-rt/lib/asan/asan_poisoning.cpp
+++ b/compiler-rt/lib/asan/asan_poisoning.cpp
@@ -19,6 +19,7 @@
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_flags.h"
#include "sanitizer_common/sanitizer_interface_internal.h"
+#include "sanitizer_common/sanitizer_internal_defs.h"
#include "sanitizer_common/sanitizer_libc.h"
#include "sanitizer_common/sanitizer_ring_buffer.h"
#include "sanitizer_common/sanitizer_stackdepot.h"
@@ -45,19 +46,20 @@
poison_records->push(new_record);
}
-bool FindPoisonRecord(uptr addr, PoisonRecord &match) {
+bool FindPoisonRecord(uptr addr, PoisonRecord& match, bool& is_full) {
if (flags()->poison_history_size <= 0)
return false;
GenericScopedLock<Mutex> l(&poison_records_mutex);
- if (poison_records) {
- for (unsigned int i = 0; i < poison_records->size(); i++) {
- PoisonRecord record = (*poison_records)[i];
- if (record.begin <= addr && addr < record.end) {
- internal_memcpy(&match, &record, sizeof(record));
- return true;
- }
+ const uptr records_count = poison_records ? poison_records->size() : 0;
+ is_full = records_count >= static_cast<uptr>(flags()->poison_history_size);
+
+ for (uptr i = 0; i < records_count; i++) {
+ PoisonRecord record = (*poison_records)[i];
+ if (record.begin <= addr && addr < record.end) {
+ internal_memcpy(&match, &record, sizeof(record));
+ return true;
}
}
diff --git a/compiler-rt/lib/asan/asan_poisoning.h b/compiler-rt/lib/asan/asan_poisoning.h
index 4b2d622..1490d88 100644
--- a/compiler-rt/lib/asan/asan_poisoning.h
+++ b/compiler-rt/lib/asan/asan_poisoning.h
@@ -30,7 +30,7 @@
};
void AddPoisonRecord(const PoisonRecord& new_record);
-bool FindPoisonRecord(uptr addr, PoisonRecord& match);
+bool FindPoisonRecord(uptr addr, PoisonRecord& match, bool& is_full);
void AcquirePoisonRecords();
void ReleasePoisonRecords();