Commit cae6c97a authored by Soren Lassen's avatar Soren Lassen Committed by Anton Likhtarov

Fix folly memory leaks found with clang:dev + asan.

Summary: I tried running folly/test with clang:dev and asan and found these leaks.

Test Plan:
unit tests with clang:dev/asan

Reviewed By: davejwatson@fb.com

Subscribers: davejwatson, trunkagent, mathieubaudet, njormrod, meyering, philipp

FB internal diff: D1569246
parent 395c7e78
......@@ -201,12 +201,11 @@ void SocketAddress::setFromLocalAddress(int socket) {
}
void SocketAddress::setFromSockaddr(const struct sockaddr* address) {
uint16_t port;
if (address->sa_family == AF_INET) {
storage_.addr = folly::IPAddress(address);
port_ = ntohs(((sockaddr_in*)address)->sin_port);
port = ntohs(((sockaddr_in*)address)->sin_port);
} else if (address->sa_family == AF_INET6) {
storage_.addr = folly::IPAddress(address);
port_ = ntohs(((sockaddr_in6*)address)->sin6_port);
port = ntohs(((sockaddr_in6*)address)->sin6_port);
} else if (address->sa_family == AF_UNIX) {
// We need an explicitly specified length for AF_UNIX addresses,
// to be able to distinguish anonymous addresses from addresses
......@@ -220,7 +219,12 @@ void SocketAddress::setFromSockaddr(const struct sockaddr* address) {
"SocketAddress::setFromSockaddr() called "
"with unsupported address type");
}
external_ = false;
if (getFamily() == AF_UNIX) {
storage_.un.free();
external_ = false;
}
storage_.addr = folly::IPAddress(address);
port_ = port;
}
void SocketAddress::setFromSockaddr(const struct sockaddr* address,
......
......@@ -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>::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
......
......@@ -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<typename T>
struct SyncVec {
PackedSyncPtr<T> 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)));
......
......@@ -184,7 +184,7 @@ TEST(ThreadLocal, SimpleRepeatDestructor) {
TEST(ThreadLocal, InterleavedDestructors) {
Widget::totalVal_ = 0;
ThreadLocal<Widget>* w = nullptr;
std::unique_ptr<ThreadLocal<Widget>> w;
int wVersion = 0;
const int wVersionMax = 2;
int thIter = 0;
......@@ -214,8 +214,7 @@ TEST(ThreadLocal, InterleavedDestructors) {
{
std::lock_guard<std::mutex> g(lock);
thIterPrev = thIter;
delete w;
w = new ThreadLocal<Widget>();
w.reset(new ThreadLocal<Widget>());
++wVersion;
}
while (true) {
......
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