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
}
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
"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,
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 {
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
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)
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)));
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;
{
std::lock_guard<std::mutex> g(lock);
thIterPrev = thIter;
- delete w;
- w = new ThreadLocal<Widget>();
+ w.reset(new ThreadLocal<Widget>());
++wVersion;
}
while (true) {