#include <folly/Conv.h>
#include <folly/Exception.h>
+#include <folly/ScopeGuard.h>
namespace folly {
namespace symbolizer {
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) {
errno = EINVAL;
return kInvalidElfFile;
}
-
+ guard.dismiss();
return kSuccess;
}
ElfFile::~ElfFile() {
- destroy();
+ reset();
}
ElfFile::ElfFile(ElfFile&& other) noexcept
ElfFile& ElfFile::operator=(ElfFile&& other) {
assert(this != &other);
- destroy();
+ reset();
fd_ = other.fd_;
file_ = other.file_;
return *this;
}
-void ElfFile::destroy() {
+void ElfFile::reset() {
if (file_ != MAP_FAILED) {
munmap(file_, length_);
+ file_ = static_cast<char*>(MAP_FAILED);
}
if (fd_ != -1) {
close(fd_);
+ fd_ = -1;
}
}
private:
bool init(const char** msg);
- void destroy();
+ void reset();
ElfFile(const ElfFile&) = delete;
ElfFile& operator=(const ElfFile&) = delete;