From 09333606448a9499e0affd0d780c90d8a4dd7572 Mon Sep 17 00:00:00 2001 From: Zhichao Cao Date: Tue, 22 Oct 2019 16:38:13 -0700 Subject: [PATCH] Fix the potential memory leak in trace_replay (#5955) Summary: In the previous PR https://github.com/facebook/rocksdb/issues/5934 , in the while loop, if/else if is used without ending with else to free the object referenced by ra, it might cause potential memory leak (warning during compiling). Fix it by changing the last "else if" to "else". Pull Request resolved: https://github.com/facebook/rocksdb/pull/5955 Test Plan: pass make asan check, pass the USE_CLANG=1 TEST_TMPDIR=/dev/shm/rocksdb OPT=-g make -j64 analyze. Differential Revision: D18071612 Pulled By: zhichao-cao fbshipit-source-id: 51c00023d0c97c2921507254329aed55d56e1786 --- trace_replay/trace_replay.cc | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/trace_replay/trace_replay.cc b/trace_replay/trace_replay.cc index b643e620e..41d98829b 100644 --- a/trace_replay/trace_replay.cc +++ b/trace_replay/trace_replay.cc @@ -315,11 +315,10 @@ Status Replayer::MultiThreadReplay(uint32_t threads_num) { ReadOptions roptions; uint64_t ops = 0; while (s.ok()) { - ReplayerWorkerArg* ra = new ReplayerWorkerArg; + std::unique_ptr ra(new ReplayerWorkerArg); ra->db = db_; s = ReadTrace(&(ra->trace_entry)); if (!s.ok()) { - delete ra; break; } ra->woptions = woptions; @@ -329,23 +328,29 @@ Status Replayer::MultiThreadReplay(uint32_t threads_num) { replay_epoch + std::chrono::microseconds( (ra->trace_entry.ts - header.ts) / fast_forward_)); if (ra->trace_entry.type == kTraceWrite) { - thread_pool.Schedule(&Replayer::BGWorkWriteBatch, ra, nullptr, nullptr); + thread_pool.Schedule(&Replayer::BGWorkWriteBatch, ra.release(), nullptr, + nullptr); ops++; } else if (ra->trace_entry.type == kTraceGet) { - thread_pool.Schedule(&Replayer::BGWorkGet, ra, nullptr, nullptr); + thread_pool.Schedule(&Replayer::BGWorkGet, ra.release(), nullptr, + nullptr); ops++; } else if (ra->trace_entry.type == kTraceIteratorSeek) { - thread_pool.Schedule(&Replayer::BGWorkIterSeek, ra, nullptr, nullptr); + thread_pool.Schedule(&Replayer::BGWorkIterSeek, ra.release(), nullptr, + nullptr); ops++; } else if (ra->trace_entry.type == kTraceIteratorSeekForPrev) { - thread_pool.Schedule(&Replayer::BGWorkIterSeekForPrev, ra, nullptr, - nullptr); + thread_pool.Schedule(&Replayer::BGWorkIterSeekForPrev, ra.release(), + nullptr, nullptr); ops++; } else if (ra->trace_entry.type == kTraceEnd) { // Do nothing for now. // TODO: Add some validations later. - delete ra; break; + } else { + // Other trace entry types that are not implemented for replay. + // To finish the replay, we continue the process. + continue; } }