Use malloc/free for LRUHandle instead of new[]/delete[] (#10884)

Summary:
It's unsafe to call `malloc_usable_size` with an address not returned by a function from the `malloc` family (see https://github.com/facebook/rocksdb/issues/10798). The patch switches from using `new[]` / `delete[]` for `LRUHandle` to `malloc` / `free`.

Pull Request resolved: https://github.com/facebook/rocksdb/pull/10884

Test Plan: `make check`

Reviewed By: pdillinger

Differential Revision: D40738089

Pulled By: ltamasi

fbshipit-source-id: ac5583f88125fee49c314639be6b6df85937fbee
main
Levi Tamasi 2 years ago committed by Facebook GitHub Bot
parent 56715350d9
commit 22ff8c5af7
  1. 9
      cache/lru_cache.cc
  2. 4
      cache/lru_cache.h

@ -386,7 +386,7 @@ Status LRUCacheShard::InsertItem(LRUHandle* e, LRUHandle** handle,
last_reference_list.push_back(e); last_reference_list.push_back(e);
} else { } else {
if (free_handle_on_fail) { if (free_handle_on_fail) {
delete[] reinterpret_cast<char*>(e); free(e);
*handle = nullptr; *handle = nullptr;
} }
s = Status::MemoryLimit("Insert failed due to LRU cache being full."); s = Status::MemoryLimit("Insert failed due to LRU cache being full.");
@ -559,8 +559,7 @@ LRUHandle* LRUCacheShard::Lookup(const Slice& key, uint32_t hash,
secondary_cache_->Lookup(key, create_cb, wait, found_dummy_entry, secondary_cache_->Lookup(key, create_cb, wait, found_dummy_entry,
is_in_sec_cache); is_in_sec_cache);
if (secondary_handle != nullptr) { if (secondary_handle != nullptr) {
e = reinterpret_cast<LRUHandle*>( e = static_cast<LRUHandle*>(malloc(sizeof(LRUHandle) - 1 + key.size()));
new char[sizeof(LRUHandle) - 1 + key.size()]);
e->m_flags = 0; e->m_flags = 0;
e->im_flags = 0; e->im_flags = 0;
@ -683,8 +682,8 @@ Status LRUCacheShard::Insert(const Slice& key, uint32_t hash, void* value,
// Allocate the memory here outside of the mutex. // Allocate the memory here outside of the mutex.
// If the cache is full, we'll have to release it. // If the cache is full, we'll have to release it.
// It shouldn't happen very often though. // It shouldn't happen very often though.
LRUHandle* e = reinterpret_cast<LRUHandle*>( LRUHandle* e =
new char[sizeof(LRUHandle) - 1 + key.size()]); static_cast<LRUHandle*>(malloc(sizeof(LRUHandle) - 1 + key.size()));
e->value = value; e->value = value;
e->m_flags = 0; e->m_flags = 0;

4
cache/lru_cache.h vendored

@ -212,6 +212,7 @@ struct LRUHandle {
void Free() { void Free() {
assert(refs == 0); assert(refs == 0);
if (!IsSecondaryCacheCompatible() && info_.deleter) { if (!IsSecondaryCacheCompatible() && info_.deleter) {
(*info_.deleter)(key(), value); (*info_.deleter)(key(), value);
} else if (IsSecondaryCacheCompatible()) { } else if (IsSecondaryCacheCompatible()) {
@ -226,7 +227,8 @@ struct LRUHandle {
(*info_.helper->del_cb)(key(), value); (*info_.helper->del_cb)(key(), value);
} }
} }
delete[] reinterpret_cast<char*>(this);
free(this);
} }
inline size_t CalcuMetaCharge( inline size_t CalcuMetaCharge(

Loading…
Cancel
Save