Commit 8c50aa30 authored by Roman Lebedev's avatar Roman Lebedev

Cache: dt_cache_release_with_caller(): if no other readers, poison.

We are using pthread's rwlock.
At any given point in time, there can be either
one(!) writer, or many readers.

If we are unlocking writer, then there are no other
clients (with read lock).
If we are unlocking reader, there may be other readers.

So if we are unlocking the last read lock, only then
can we poison the memory. Else, we will get false
use-after-user-poison.

FIXME: yes, this is *HIGHLY* unportable and
is accessing implementation details. Once we migrate
to CK, this should probably get better.

Since this is only needed when compiling with ASAN,
whoever wants to compile with ASAN with different
pthread implementation shall simply change 1 to 0
in #if
parent e2902888
......@@ -364,6 +364,20 @@ void dt_cache_gc(dt_cache_t *cache, const float fill_ratio)
void dt_cache_release_with_caller(dt_cache_t *cache, dt_cache_entry_t *entry, const char *file, int line)
{
#if((__has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)) && 1)
// yes, this is *HIGHLY* unportable and is accessing implementation details.
#ifdef _DEBUG
if(entry->lock.lock.__data.__nr_readers <= 1)
#else
if(entry->lock.__data.__nr_readers <= 1)
#endif
{
// only if there are no other reades we may poison.
assert(entry->data_size);
ASAN_POISON_MEMORY_REGION(entry->data, entry->data_size);
}
#endif
dt_pthread_rwlock_unlock(&entry->lock);
}
......
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