From: Soren Lassen Date: Wed, 24 Sep 2014 20:34:17 +0000 (-0700) Subject: Fix some folly memory leaks found with clang:dev + asan X-Git-Tag: v0.22.0~327 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=03e99d2e90996a2a424a20b1a99c90d245344a7e;p=folly.git Fix some folly memory leaks found with clang:dev + asan Summary: Reverts the revert of the small_vector and test parts of D1569246. I'm saving the SocketAddress fix for later, because it caused problems and needs more research. Test Plan: unit tests with clang:dev/asan Reviewed By: njormrod@fb.com Subscribers: mathieubaudet, philipp, meyering, njormrod FB internal diff: D1575574 Blame Revision: D1575190 --- diff --git a/folly/small_vector.h b/folly/small_vector.h index 92a5a2fc..132ff241 100644 --- a/folly/small_vector.h +++ b/folly/small_vector.h @@ -391,13 +391,16 @@ public: try { std::uninitialized_copy(o.begin(), o.end(), begin()); } catch (...) { - if (this->isExtern()) u.freeHeap(); + if (this->isExtern()) { + u.freeHeap(); + } throw; } this->setSize(n); } - small_vector(small_vector&& o) { + small_vector(small_vector&& o) + noexcept(std::is_nothrow_move_constructible::value) { if (o.isExtern()) { swap(o); } else { @@ -877,18 +880,31 @@ private: auto distance = std::distance(first, last); makeSize(distance); this->setSize(distance); - - detail::populateMemForward(data(), distance, - [&] (void* p) { new (p) value_type(*first++); } - ); + try { + detail::populateMemForward(data(), distance, + [&] (void* p) { new (p) value_type(*first++); } + ); + } catch (...) { + if (this->isExtern()) { + u.freeHeap(); + } + throw; + } } void doConstruct(size_type n, value_type const& val) { makeSize(n); this->setSize(n); - detail::populateMemForward(data(), n, - [&] (void* p) { new (p) value_type(val); } - ); + try { + detail::populateMemForward(data(), n, + [&] (void* p) { new (p) value_type(val); } + ); + } catch (...) { + if (this->isExtern()) { + u.freeHeap(); + } + throw; + } } // The true_type means we should forward to the size_t,value_type diff --git a/folly/test/PackedSyncPtrTest.cpp b/folly/test/PackedSyncPtrTest.cpp index adcc3504..f926d6ff 100644 --- a/folly/test/PackedSyncPtrTest.cpp +++ b/folly/test/PackedSyncPtrTest.cpp @@ -61,6 +61,7 @@ TEST(PackedSyncPtr, Basic) { EXPECT_EQ(sp.extra(), 0x13); EXPECT_EQ(sp.get(), newP); sp.unlock(); + delete sp.get(); } // Here we use the PackedSyncPtr to lock the whole SyncVec (base, *base, and sz) @@ -68,6 +69,7 @@ template struct SyncVec { PackedSyncPtr base; SyncVec() { base.init(); } + ~SyncVec() { free(base.get()); } void push_back(const T& t) { base.set((T*) realloc(base.get(), (base.extra() + 1) * sizeof(T))); diff --git a/folly/test/ThreadLocalTest.cpp b/folly/test/ThreadLocalTest.cpp index 36917139..e2911744 100644 --- a/folly/test/ThreadLocalTest.cpp +++ b/folly/test/ThreadLocalTest.cpp @@ -184,7 +184,7 @@ TEST(ThreadLocal, SimpleRepeatDestructor) { TEST(ThreadLocal, InterleavedDestructors) { Widget::totalVal_ = 0; - ThreadLocal* w = nullptr; + std::unique_ptr> w; int wVersion = 0; const int wVersionMax = 2; int thIter = 0; @@ -214,8 +214,7 @@ TEST(ThreadLocal, InterleavedDestructors) { { std::lock_guard g(lock); thIterPrev = thIter; - delete w; - w = new ThreadLocal(); + w.reset(new ThreadLocal()); ++wVersion; } while (true) {