From 5d27d65bef4ec40fb7bb61f4f50817279abd85eb Mon Sep 17 00:00:00 2001 From: Zhongyi Xie Date: Fri, 3 May 2019 15:55:48 -0700 Subject: [PATCH] multiget: fix memory issues due to vector auto resizing (#5279) Summary: This PR fixes three memory issues found by ASAN * in db_stress, the key vector for MultiGet is created using `emplace_back` which could potentially invalidates references to the underlying storage (vector) due to auto resizing. Fix by calling reserve in advance. * Similar issue in construction of GetContext autovector in version_set.cc * In multiget_context.h use T[] specialization for unique_ptr that holds a char array Pull Request resolved: https://github.com/facebook/rocksdb/pull/5279 Differential Revision: D15202893 Pulled By: miasantreble fbshipit-source-id: 14cc2cda0ed64d29f2a1e264a6bfdaa4294ee75d --- db/version_set.cc | 6 +++++- table/multiget_context.h | 2 +- tools/db_stress.cc | 6 ++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/db/version_set.cc b/db/version_set.cc index 63d5af3af..6d4fb7315 100644 --- a/db/version_set.cc +++ b/db/version_set.cc @@ -1774,7 +1774,11 @@ void Version::MultiGet(const ReadOptions& read_options, MultiGetRange* range, iter->value, nullptr, &(iter->merge_context), &iter->max_covering_tombstone_seq, this->env_, &iter->seq, merge_operator_ ? &pinned_iters_mgr : nullptr, callback, is_blob); - iter->get_context = &get_ctx.back(); + } + int get_ctx_index = 0; + for (auto iter = range->begin(); iter != range->end(); + ++iter, get_ctx_index++) { + iter->get_context = &(get_ctx[get_ctx_index]); } MultiGetRange file_picker_range(*range, range->begin(), range->end()); diff --git a/table/multiget_context.h b/table/multiget_context.h index d3a8d0946..c9e682fad 100644 --- a/table/multiget_context.h +++ b/table/multiget_context.h @@ -123,7 +123,7 @@ class MultiGetContext { KeyContext** sorted_keys_; size_t num_keys_; uint64_t value_mask_; - std::unique_ptr lookup_key_heap_buf; + std::unique_ptr lookup_key_heap_buf; LookupKey* lookup_key_ptr_; public: diff --git a/tools/db_stress.cc b/tools/db_stress.cc index 4ed66ed6d..c6959802b 100644 --- a/tools/db_stress.cc +++ b/tools/db_stress.cc @@ -3057,6 +3057,8 @@ class NonBatchedOpsStressTest : public StressTest { size_t num_keys = rand_keys.size(); std::vector key_str; std::vector keys; + key_str.reserve(num_keys); + keys.reserve(num_keys); std::vector values(num_keys); std::vector statuses(num_keys); ColumnFamilyHandle* cfh = column_families_[rand_column_families[0]]; @@ -3615,6 +3617,8 @@ class BatchedOpsStressTest : public StressTest { ReadOptions readoptionscopy = readoptions; readoptionscopy.snapshot = db_->GetSnapshot(); std::vector key_str; + key_str.reserve(num_keys); + key_slices.reserve(num_keys); std::string from_db; ColumnFamilyHandle* cfh = column_families_[rand_column_families[0]]; @@ -3888,6 +3892,8 @@ class AtomicFlushStressTest : public StressTest { size_t num_keys = rand_keys.size(); std::vector key_str; std::vector keys; + keys.reserve(num_keys); + key_str.reserve(num_keys); std::vector values(num_keys); std::vector statuses(num_keys); ColumnFamilyHandle* cfh = column_families_[rand_column_families[0]];