From: Laurent Demailly Date: Wed, 17 Dec 2014 01:56:51 +0000 (-0800) Subject: fix bug with elf object left with file open upon error causing Entered fatal signal... X-Git-Tag: v0.22.0~92 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=56b62698258fdf345415615c1d95c318024590aa;p=folly.git fix bug with elf object left with file open upon error causing Entered fatal signal handler recursively later Summary: fix bug with elf object left with file open upon error causing Entered fatal signal handler recursively later Test Plan: run publisher at the limit Reviewed By: tudorb@fb.com Subscribers: trunkagent, chip, folly-diffs@ FB internal diff: D1743052 Tasks: 5752190 Signature: t1:1743052:1418780889:ad2ee0e6999cf417c2b9fd1ef6bc82d2086774a1 --- diff --git a/folly/experimental/symbolizer/Elf.cpp b/folly/experimental/symbolizer/Elf.cpp index 6b32dc12..00b0e9ef 100644 --- a/folly/experimental/symbolizer/Elf.cpp +++ b/folly/experimental/symbolizer/Elf.cpp @@ -28,6 +28,7 @@ #include #include +#include namespace folly { namespace symbolizer { @@ -65,7 +66,10 @@ int ElfFile::openNoThrow(const char* name, bool readOnly, const char** msg) if (msg) *msg = "open"; return kSystemError; } - + // Always close fd and unmap in case of failure along the way to avoid + // check failure above if we leave fd != -1 and the object is recycled + // like it is inside SignalSafeElfCache + ScopeGuard guard = makeGuard([&]{ reset(); }); struct stat st; int r = fstat(fd_, &st); if (r == -1) { @@ -87,12 +91,12 @@ int ElfFile::openNoThrow(const char* name, bool readOnly, const char** msg) errno = EINVAL; return kInvalidElfFile; } - + guard.dismiss(); return kSuccess; } ElfFile::~ElfFile() { - destroy(); + reset(); } ElfFile::ElfFile(ElfFile&& other) noexcept @@ -108,7 +112,7 @@ ElfFile::ElfFile(ElfFile&& other) noexcept ElfFile& ElfFile::operator=(ElfFile&& other) { assert(this != &other); - destroy(); + reset(); fd_ = other.fd_; file_ = other.file_; @@ -123,13 +127,15 @@ ElfFile& ElfFile::operator=(ElfFile&& other) { return *this; } -void ElfFile::destroy() { +void ElfFile::reset() { if (file_ != MAP_FAILED) { munmap(file_, length_); + file_ = static_cast(MAP_FAILED); } if (fd_ != -1) { close(fd_); + fd_ = -1; } } diff --git a/folly/experimental/symbolizer/Elf.h b/folly/experimental/symbolizer/Elf.h index 9a58ba2f..fe96354a 100644 --- a/folly/experimental/symbolizer/Elf.h +++ b/folly/experimental/symbolizer/Elf.h @@ -193,7 +193,7 @@ class ElfFile { private: bool init(const char** msg); - void destroy(); + void reset(); ElfFile(const ElfFile&) = delete; ElfFile& operator=(const ElfFile&) = delete;