From 04458d15323e21e0384f9d74bace8c1fcc8895bc Mon Sep 17 00:00:00 2001 From: Yedidya Feldblum Date: Fri, 21 Jul 2017 01:45:34 -0700 Subject: [PATCH] Apply clang-format to folly/experimental/symbolizer/ Summary: [Folly] Apply `clang-format` to `folly/experimental/symbolizer/`. Reviewed By: Orvid Differential Revision: D5468832 fbshipit-source-id: 94a0f82312769be0e8be724c11f97e14425ead10 --- folly/experimental/symbolizer/Dwarf.cpp | 381 +++++++++--------- folly/experimental/symbolizer/Dwarf.h | 74 ++-- folly/experimental/symbolizer/Elf-inl.h | 41 +- folly/experimental/symbolizer/Elf.cpp | 208 ++++++---- folly/experimental/symbolizer/Elf.h | 86 ++-- folly/experimental/symbolizer/ElfCache.cpp | 9 +- folly/experimental/symbolizer/ElfCache.h | 12 +- folly/experimental/symbolizer/ElfUtil.cpp | 7 +- folly/experimental/symbolizer/LineReader.cpp | 24 +- folly/experimental/symbolizer/LineReader.h | 9 +- .../experimental/symbolizer/SignalHandler.cpp | 55 +-- folly/experimental/symbolizer/SignalHandler.h | 7 +- folly/experimental/symbolizer/StackTrace.cpp | 13 +- folly/experimental/symbolizer/StackTrace.h | 7 +- folly/experimental/symbolizer/Symbolizer.cpp | 88 ++-- folly/experimental/symbolizer/Symbolizer.h | 79 ++-- .../symbolizer/test/DwarfTests.cpp | 59 +-- .../experimental/symbolizer/test/ElfTests.cpp | 11 +- .../symbolizer/test/LineReaderTest.cpp | 27 +- .../symbolizer/test/SignalHandlerTest.cpp | 13 +- .../symbolizer/test/SignalHandlerTest.h | 11 +- .../symbolizer/test/StackTraceTest.cpp | 2 +- .../symbolizer/test/SymbolizerTest.cpp | 18 +- 23 files changed, 647 insertions(+), 594 deletions(-) diff --git a/folly/experimental/symbolizer/Dwarf.cpp b/folly/experimental/symbolizer/Dwarf.cpp index b0ec5cb0..f50a18c0 100644 --- a/folly/experimental/symbolizer/Dwarf.cpp +++ b/folly/experimental/symbolizer/Dwarf.cpp @@ -31,8 +31,7 @@ Dwarf::Dwarf(const ElfFile* elf) : elf_(elf) { init(); } -Dwarf::Section::Section(folly::StringPiece d) : is64Bit_(false), data_(d) { -} +Dwarf::Section::Section(folly::StringPiece d) : is64Bit_(false), data_(d) {} namespace { @@ -41,8 +40,8 @@ namespace { // Read (bitwise) one object of type T template -typename std::enable_if::value, T>::type -read(folly::StringPiece& sp) { +typename std::enable_if::value, T>::type read( + folly::StringPiece& sp) { FOLLY_SAFE_CHECK(sp.size() >= sizeof(T), "underflow"); T x; memcpy(&x, sp.data(), sizeof(T)); @@ -75,7 +74,7 @@ int64_t readSLEB(folly::StringPiece& sp) { uint64_t r = readULEB(sp, shift, val); if (shift < 64 && (val & 0x40)) { - r |= -(1ULL << shift); // sign extend + r |= -(1ULL << shift); // sign extend } return r; @@ -96,8 +95,7 @@ folly::StringPiece readBytes(folly::StringPiece& sp, uint64_t len) { // Read a null-terminated string folly::StringPiece readNullTerminated(folly::StringPiece& sp) { - const char* p = static_cast( - memchr(sp.data(), 0, sp.size())); + const char* p = static_cast(memchr(sp.data(), 0, sp.size())); FOLLY_SAFE_CHECK(p, "invalid null-terminated string"); folly::StringPiece ret(sp.data(), p); sp.assign(p + 1, sp.end()); @@ -151,7 +149,8 @@ void simplifyPath(folly::StringPiece& sp) { } // Strip trailing slashes, except when this is the root path. - while (sp.size() > 1 && sp.removeSuffix('/')) { } + while (sp.size() > 1 && sp.removeSuffix('/')) { + } if (sp.removeSuffix("/.")) { continue; @@ -161,13 +160,13 @@ void simplifyPath(folly::StringPiece& sp) { } } -} // namespace +} // namespace -Dwarf::Path::Path(folly::StringPiece baseDir, folly::StringPiece subDir, - folly::StringPiece file) - : baseDir_(baseDir), - subDir_(subDir), - file_(file) { +Dwarf::Path::Path( + folly::StringPiece baseDir, + folly::StringPiece subDir, + folly::StringPiece file) + : baseDir_(baseDir), subDir_(subDir), file_(file) { using std::swap; // Normalize @@ -184,7 +183,7 @@ Dwarf::Path::Path(folly::StringPiece baseDir, folly::StringPiece subDir, } if (!subDir_.empty() && subDir_[0] == '/') { - baseDir_.clear(); // subDir_ is absolute + baseDir_.clear(); // subDir_ is absolute } simplifyPath(baseDir_); @@ -224,7 +223,7 @@ size_t Dwarf::Path::toBuffer(char* buf, size_t bufSize) const { size_t totalSize = 0; bool needsSlash = false; - auto append = [&] (folly::StringPiece sp) { + auto append = [&](folly::StringPiece sp) { if (bufSize >= 2) { size_t toCopy = std::min(sp.size(), bufSize - 1); memcpy(buf, sp.data(), toCopy); @@ -327,8 +326,9 @@ void Dwarf::init() { getSection(".debug_aranges", &aranges_); } -bool Dwarf::readAbbreviation(folly::StringPiece& section, - DIEAbbreviation& abbr) { +bool Dwarf::readAbbreviation( + folly::StringPiece& section, + DIEAbbreviation& abbr) { // abbreviation code abbr.code = readULEB(section); if (abbr.code == 0) { @@ -355,13 +355,12 @@ bool Dwarf::readAbbreviation(folly::StringPiece& section, return true; } -Dwarf::DIEAbbreviation::Attribute Dwarf::readAttribute( - folly::StringPiece& sp) { - return { readULEB(sp), readULEB(sp) }; +Dwarf::DIEAbbreviation::Attribute Dwarf::readAttribute(folly::StringPiece& sp) { + return {readULEB(sp), readULEB(sp)}; } Dwarf::DIEAbbreviation Dwarf::getAbbreviation(uint64_t code, uint64_t offset) - const { + const { // Linear search in the .debug_abbrev section, starting at offset folly::StringPiece section = abbrev_; section.advance(offset); @@ -377,51 +376,53 @@ Dwarf::DIEAbbreviation Dwarf::getAbbreviation(uint64_t code, uint64_t offset) } Dwarf::AttributeValue Dwarf::readAttributeValue( - folly::StringPiece& sp, uint64_t form, bool is64Bit) const { + folly::StringPiece& sp, + uint64_t form, + bool is64Bit) const { switch (form) { - case DW_FORM_addr: - return read(sp); - case DW_FORM_block1: - return readBytes(sp, read(sp)); - case DW_FORM_block2: - return readBytes(sp, read(sp)); - case DW_FORM_block4: - return readBytes(sp, read(sp)); - case DW_FORM_block: // fallthrough - case DW_FORM_exprloc: - return readBytes(sp, readULEB(sp)); - case DW_FORM_data1: // fallthrough - case DW_FORM_ref1: - return read(sp); - case DW_FORM_data2: // fallthrough - case DW_FORM_ref2: - return read(sp); - case DW_FORM_data4: // fallthrough - case DW_FORM_ref4: - return read(sp); - case DW_FORM_data8: // fallthrough - case DW_FORM_ref8: - return read(sp); - case DW_FORM_sdata: - return readSLEB(sp); - case DW_FORM_udata: // fallthrough - case DW_FORM_ref_udata: - return readULEB(sp); - case DW_FORM_flag: - return read(sp); - case DW_FORM_flag_present: - return 1; - case DW_FORM_sec_offset: // fallthrough - case DW_FORM_ref_addr: - return readOffset(sp, is64Bit); - case DW_FORM_string: - return readNullTerminated(sp); - case DW_FORM_strp: - return getStringFromStringSection(readOffset(sp, is64Bit)); - case DW_FORM_indirect: // form is explicitly specified - return readAttributeValue(sp, readULEB(sp), is64Bit); - default: - FOLLY_SAFE_CHECK(false, "invalid attribute form"); + case DW_FORM_addr: + return read(sp); + case DW_FORM_block1: + return readBytes(sp, read(sp)); + case DW_FORM_block2: + return readBytes(sp, read(sp)); + case DW_FORM_block4: + return readBytes(sp, read(sp)); + case DW_FORM_block: // fallthrough + case DW_FORM_exprloc: + return readBytes(sp, readULEB(sp)); + case DW_FORM_data1: // fallthrough + case DW_FORM_ref1: + return read(sp); + case DW_FORM_data2: // fallthrough + case DW_FORM_ref2: + return read(sp); + case DW_FORM_data4: // fallthrough + case DW_FORM_ref4: + return read(sp); + case DW_FORM_data8: // fallthrough + case DW_FORM_ref8: + return read(sp); + case DW_FORM_sdata: + return readSLEB(sp); + case DW_FORM_udata: // fallthrough + case DW_FORM_ref_udata: + return readULEB(sp); + case DW_FORM_flag: + return read(sp); + case DW_FORM_flag_present: + return 1; + case DW_FORM_sec_offset: // fallthrough + case DW_FORM_ref_addr: + return readOffset(sp, is64Bit); + case DW_FORM_string: + return readNullTerminated(sp); + case DW_FORM_strp: + return getStringFromStringSection(readOffset(sp, is64Bit)); + case DW_FORM_indirect: // form is explicitly specified + return readAttributeValue(sp, readULEB(sp), is64Bit); + default: + FOLLY_SAFE_CHECK(false, "invalid attribute form"); } } @@ -436,9 +437,10 @@ folly::StringPiece Dwarf::getStringFromStringSection(uint64_t offset) const { * Find @address in .debug_aranges and return the offset in * .debug_info for compilation unit to which this address belongs. */ -bool Dwarf::findDebugInfoOffset(uintptr_t address, - StringPiece aranges, - uint64_t& offset) { +bool Dwarf::findDebugInfoOffset( + uintptr_t address, + StringPiece aranges, + uint64_t& offset) { Section arangesSection(aranges); folly::StringPiece chunk; while (arangesSection.next(chunk)) { @@ -478,9 +480,10 @@ bool Dwarf::findDebugInfoOffset(uintptr_t address, * Returns whether the address was found. * Advances @sp to the next entry in .debug_info. */ -bool Dwarf::findLocation(uintptr_t address, - StringPiece& infoEntry, - LocationInfo& locationInfo) const { +bool Dwarf::findLocation( + uintptr_t address, + StringPiece& infoEntry, + LocationInfo& locationInfo) const { // For each compilation unit compiled with a DWARF producer, a // contribution is made to the .debug_info section of the object // file. Each such contribution consists of a compilation unit @@ -511,8 +514,8 @@ bool Dwarf::findLocation(uintptr_t address, auto code = readULEB(chunk); FOLLY_SAFE_CHECK(code != 0, "invalid code"); auto abbr = getAbbreviation(code, abbrevOffset); - FOLLY_SAFE_CHECK(abbr.tag == DW_TAG_compile_unit, - "expecting compile unit entry"); + FOLLY_SAFE_CHECK( + abbr.tag == DW_TAG_compile_unit, "expecting compile unit entry"); // Skip children entries, advance to the next compilation unit entry. infoEntry.advance(chunk.end() - infoEntry.begin()); @@ -529,23 +532,22 @@ bool Dwarf::findLocation(uintptr_t address, if (attr.name == 0 && attr.form == 0) { break; } - auto val = readAttributeValue(chunk, attr.form, - debugInfoSection.is64Bit()); + auto val = readAttributeValue(chunk, attr.form, debugInfoSection.is64Bit()); switch (attr.name) { - case DW_AT_stmt_list: - // Offset in .debug_line for the line number VM program for this - // compilation unit - lineOffset = boost::get(val); - foundLineOffset = true; - break; - case DW_AT_comp_dir: - // Compilation directory - compilationDirectory = boost::get(val); - break; - case DW_AT_name: - // File name of main file being compiled - mainFileName = boost::get(val); - break; + case DW_AT_stmt_list: + // Offset in .debug_line for the line number VM program for this + // compilation unit + lineOffset = boost::get(val); + foundLineOffset = true; + break; + case DW_AT_comp_dir: + // Compilation directory + compilationDirectory = boost::get(val); + break; + case DW_AT_name: + // File name of main file being compiled + mainFileName = boost::get(val); + break; } } @@ -568,9 +570,10 @@ bool Dwarf::findLocation(uintptr_t address, return locationInfo.hasFileAndLine; } -bool Dwarf::findAddress(uintptr_t address, - LocationInfo& locationInfo, - LocationInfoMode mode) const { +bool Dwarf::findAddress( + uintptr_t address, + LocationInfo& locationInfo, + LocationInfoMode mode) const { locationInfo = LocationInfo(); if (mode == LocationInfoMode::DISABLED) { @@ -603,7 +606,6 @@ bool Dwarf::findAddress(uintptr_t address, } } - // Slow path (linear scan): Iterate over all .debug_info entries // and look for the address in each compilation unit. folly::StringPiece infoEntry(info_); @@ -613,9 +615,10 @@ bool Dwarf::findAddress(uintptr_t address, return locationInfo.hasFileAndLine; } -Dwarf::LineNumberVM::LineNumberVM(folly::StringPiece data, - folly::StringPiece compilationDirectory) - : compilationDirectory_(compilationDirectory) { +Dwarf::LineNumberVM::LineNumberVM( + folly::StringPiece data, + folly::StringPiece compilationDirectory) + : compilationDirectory_(compilationDirectory) { Section section(data); FOLLY_SAFE_CHECK(section.next(data_), "invalid line number VM"); is64Bit_ = section.is64Bit(); @@ -639,21 +642,21 @@ void Dwarf::LineNumberVM::reset() { void Dwarf::LineNumberVM::init() { version_ = read(data_); - FOLLY_SAFE_CHECK(version_ >= 2 && version_ <= 4, - "invalid version in line number VM"); + FOLLY_SAFE_CHECK( + version_ >= 2 && version_ <= 4, "invalid version in line number VM"); uint64_t headerLength = readOffset(data_, is64Bit_); - FOLLY_SAFE_CHECK(headerLength <= data_.size(), - "invalid line number VM header length"); + FOLLY_SAFE_CHECK( + headerLength <= data_.size(), "invalid line number VM header length"); folly::StringPiece header(data_.data(), headerLength); data_.assign(header.end(), data_.end()); minLength_ = read(header); - if (version_ == 4) { // Version 2 and 3 records don't have this + if (version_ == 4) { // Version 2 and 3 records don't have this uint8_t maxOpsPerInstruction = read(header); FOLLY_SAFE_CHECK(maxOpsPerInstruction == 1, "VLIW not supported"); } defaultIsStmt_ = read(header); - lineBase_ = read(header); // yes, signed + lineBase_ = read(header); // yes, signed lineRange_ = read(header); opcodeBase_ = read(header); FOLLY_SAFE_CHECK(opcodeBase_ != 0, "invalid opcode base"); @@ -689,8 +692,8 @@ bool Dwarf::LineNumberVM::next(folly::StringPiece& program) { return (ret == COMMIT); } -Dwarf::LineNumberVM::FileName Dwarf::LineNumberVM::getFileName(uint64_t index) - const { +Dwarf::LineNumberVM::FileName Dwarf::LineNumberVM::getFileName( + uint64_t index) const { FOLLY_SAFE_CHECK(index != 0, "invalid file index 0"); FileName fn; @@ -714,29 +717,30 @@ Dwarf::LineNumberVM::FileName Dwarf::LineNumberVM::getFileName(uint64_t index) return fn; } -folly::StringPiece Dwarf::LineNumberVM::getIncludeDirectory(uint64_t index) - const { +folly::StringPiece Dwarf::LineNumberVM::getIncludeDirectory( + uint64_t index) const { if (index == 0) { return folly::StringPiece(); } - FOLLY_SAFE_CHECK(index <= includeDirectoryCount_, - "invalid include directory"); + FOLLY_SAFE_CHECK( + index <= includeDirectoryCount_, "invalid include directory"); folly::StringPiece includeDirectories = includeDirectories_; folly::StringPiece dir; for (; index; --index) { dir = readNullTerminated(includeDirectories); if (dir.empty()) { - abort(); // BUG + abort(); // BUG } } return dir; } -bool Dwarf::LineNumberVM::readFileName(folly::StringPiece& program, - FileName& fn) { +bool Dwarf::LineNumberVM::readFileName( + folly::StringPiece& program, + FileName& fn) { fn.relativeName = readNullTerminated(program); if (fn.relativeName.empty()) { return false; @@ -748,16 +752,17 @@ bool Dwarf::LineNumberVM::readFileName(folly::StringPiece& program, return true; } -bool Dwarf::LineNumberVM::nextDefineFile(folly::StringPiece& program, - FileName& fn) const { +bool Dwarf::LineNumberVM::nextDefineFile( + folly::StringPiece& program, + FileName& fn) const { while (!program.empty()) { auto opcode = read(program); - if (opcode >= opcodeBase_) { // special opcode + if (opcode >= opcodeBase_) { // special opcode continue; } - if (opcode != 0) { // standard opcode + if (opcode != 0) { // standard opcode // Skip, slurp the appropriate number of LEB arguments uint8_t argCount = standardOpcodeLengths_[opcode - 1]; while (argCount--) { @@ -774,8 +779,9 @@ bool Dwarf::LineNumberVM::nextDefineFile(folly::StringPiece& program, --length; if (opcode == DW_LNE_define_file) { - FOLLY_SAFE_CHECK(readFileName(program, fn), - "invalid empty file in DW_LNE_define_file"); + FOLLY_SAFE_CHECK( + readFileName(program, fn), + "invalid empty file in DW_LNE_define_file"); return true; } @@ -790,7 +796,7 @@ Dwarf::LineNumberVM::StepResult Dwarf::LineNumberVM::step( folly::StringPiece& program) { auto opcode = read(program); - if (opcode >= opcodeBase_) { // special opcode + if (opcode >= opcodeBase_) { // special opcode uint8_t adjustedOpcode = opcode - opcodeBase_; uint8_t opAdvance = adjustedOpcode / lineRange_; @@ -804,52 +810,58 @@ Dwarf::LineNumberVM::StepResult Dwarf::LineNumberVM::step( return COMMIT; } - if (opcode != 0) { // standard opcode + if (opcode != 0) { // standard opcode // Only interpret opcodes that are recognized by the version we're parsing; // the others are vendor extensions and we should ignore them. switch (opcode) { - case DW_LNS_copy: - basicBlock_ = false; - prologueEnd_ = false; - epilogueBegin_ = false; - discriminator_ = 0; - return COMMIT; - case DW_LNS_advance_pc: - address_ += minLength_ * readULEB(program); - return CONTINUE; - case DW_LNS_advance_line: - line_ += readSLEB(program); - return CONTINUE; - case DW_LNS_set_file: - file_ = readULEB(program); - return CONTINUE; - case DW_LNS_set_column: - column_ = readULEB(program); - return CONTINUE; - case DW_LNS_negate_stmt: - isStmt_ = !isStmt_; - return CONTINUE; - case DW_LNS_set_basic_block: - basicBlock_ = true; - return CONTINUE; - case DW_LNS_const_add_pc: - address_ += minLength_ * ((255 - opcodeBase_) / lineRange_); - return CONTINUE; - case DW_LNS_fixed_advance_pc: - address_ += read(program); - return CONTINUE; - case DW_LNS_set_prologue_end: - if (version_ == 2) break; // not supported in version 2 - prologueEnd_ = true; - return CONTINUE; - case DW_LNS_set_epilogue_begin: - if (version_ == 2) break; // not supported in version 2 - epilogueBegin_ = true; - return CONTINUE; - case DW_LNS_set_isa: - if (version_ == 2) break; // not supported in version 2 - isa_ = readULEB(program); - return CONTINUE; + case DW_LNS_copy: + basicBlock_ = false; + prologueEnd_ = false; + epilogueBegin_ = false; + discriminator_ = 0; + return COMMIT; + case DW_LNS_advance_pc: + address_ += minLength_ * readULEB(program); + return CONTINUE; + case DW_LNS_advance_line: + line_ += readSLEB(program); + return CONTINUE; + case DW_LNS_set_file: + file_ = readULEB(program); + return CONTINUE; + case DW_LNS_set_column: + column_ = readULEB(program); + return CONTINUE; + case DW_LNS_negate_stmt: + isStmt_ = !isStmt_; + return CONTINUE; + case DW_LNS_set_basic_block: + basicBlock_ = true; + return CONTINUE; + case DW_LNS_const_add_pc: + address_ += minLength_ * ((255 - opcodeBase_) / lineRange_); + return CONTINUE; + case DW_LNS_fixed_advance_pc: + address_ += read(program); + return CONTINUE; + case DW_LNS_set_prologue_end: + if (version_ == 2) { + break; // not supported in version 2 + } + prologueEnd_ = true; + return CONTINUE; + case DW_LNS_set_epilogue_begin: + if (version_ == 2) { + break; // not supported in version 2 + } + epilogueBegin_ = true; + return CONTINUE; + case DW_LNS_set_isa: + if (version_ == 2) { + break; // not supported in version 2 + } + isa_ = readULEB(program); + return CONTINUE; } // Unrecognized standard opcode, slurp the appropriate number of LEB @@ -869,19 +881,19 @@ Dwarf::LineNumberVM::StepResult Dwarf::LineNumberVM::step( --length; switch (extendedOpcode) { - case DW_LNE_end_sequence: - return END; - case DW_LNE_set_address: - address_ = read(program); - return CONTINUE; - case DW_LNE_define_file: - // We can't process DW_LNE_define_file here, as it would require us to - // use unbounded amounts of state (ie. use the heap). We'll do a second - // pass (using nextDefineFile()) if necessary. - break; - case DW_LNE_set_discriminator: - discriminator_ = readULEB(program); - return CONTINUE; + case DW_LNE_end_sequence: + return END; + case DW_LNE_set_address: + address_ = read(program); + return CONTINUE; + case DW_LNE_define_file: + // We can't process DW_LNE_define_file here, as it would require us to + // use unbounded amounts of state (ie. use the heap). We'll do a second + // pass (using nextDefineFile()) if necessary. + break; + case DW_LNE_set_discriminator: + discriminator_ = readULEB(program); + return CONTINUE; } // Unrecognized extended opcode @@ -889,8 +901,10 @@ Dwarf::LineNumberVM::StepResult Dwarf::LineNumberVM::step( return CONTINUE; } -bool Dwarf::LineNumberVM::findAddress(uintptr_t target, Path& file, - uint64_t& line) { +bool Dwarf::LineNumberVM::findAddress( + uintptr_t target, + Path& file, + uint64_t& line) { folly::StringPiece program = data_; // Within each sequence of instructions, the address may only increase. @@ -900,7 +914,7 @@ bool Dwarf::LineNumberVM::findAddress(uintptr_t target, Path& file, // a candidate crosses the target address. enum State { START, - LOW_SEQ, // candidate + LOW_SEQ, // candidate HIGH_SEQ }; State state = START; @@ -926,9 +940,10 @@ bool Dwarf::LineNumberVM::findAddress(uintptr_t target, Path& file, return false; } auto fn = getFileName(prevFile); - file = Path(compilationDirectory_, - getIncludeDirectory(fn.directoryIndex), - fn.relativeName); + file = Path( + compilationDirectory_, + getIncludeDirectory(fn.directoryIndex), + fn.relativeName); line = prevLine; return true; } @@ -945,5 +960,5 @@ bool Dwarf::LineNumberVM::findAddress(uintptr_t target, Path& file, return false; } -} // namespace symbolizer -} // namespace folly +} // namespace symbolizer +} // namespace folly diff --git a/folly/experimental/symbolizer/Dwarf.h b/folly/experimental/symbolizer/Dwarf.h index aae1b3a5..749121c6 100644 --- a/folly/experimental/symbolizer/Dwarf.h +++ b/folly/experimental/symbolizer/Dwarf.h @@ -63,14 +63,22 @@ class Dwarf { */ class Path { public: - Path() { } + Path() {} - Path(folly::StringPiece baseDir, folly::StringPiece subDir, - folly::StringPiece file); + Path( + folly::StringPiece baseDir, + folly::StringPiece subDir, + folly::StringPiece file); - folly::StringPiece baseDir() const { return baseDir_; } - folly::StringPiece subDir() const { return subDir_; } - folly::StringPiece file() const { return file_; } + folly::StringPiece baseDir() const { + return baseDir_; + } + folly::StringPiece subDir() const { + return subDir_; + } + folly::StringPiece file() const { + return file_; + } size_t size() const; @@ -121,19 +129,18 @@ class Dwarf { /** * Find the file and line number information corresponding to address. */ - bool findAddress(uintptr_t address, - LocationInfo& info, - LocationInfoMode mode) const; + bool findAddress(uintptr_t address, LocationInfo& info, LocationInfoMode mode) + const; private: - static bool findDebugInfoOffset(uintptr_t address, - StringPiece aranges, - uint64_t& offset); + static bool + findDebugInfoOffset(uintptr_t address, StringPiece aranges, uint64_t& offset); void init(); - bool findLocation(uintptr_t address, - StringPiece& infoEntry, - LocationInfo& info) const; + bool findLocation( + uintptr_t address, + StringPiece& infoEntry, + LocationInfo& info) const; const ElfFile* elf_; @@ -143,7 +150,7 @@ class Dwarf { // (yes, DWARF-32 and DWARF-64 sections may coexist in the same file) class Section { public: - Section() : is64Bit_(false) { } + Section() : is64Bit_(false) {} explicit Section(folly::StringPiece d); @@ -152,7 +159,9 @@ class Dwarf { bool next(folly::StringPiece& chunk); // Is the current chunk 64 bit? - bool is64Bit() const { return is64Bit_; } + bool is64Bit() const { + return is64Bit_; + } private: // Yes, 32- and 64- bit sections may coexist. Yikes! @@ -177,8 +186,9 @@ class Dwarf { // Interpreter for the line number bytecode VM class LineNumberVM { public: - LineNumberVM(folly::StringPiece data, - folly::StringPiece compilationDirectory); + LineNumberVM( + folly::StringPiece data, + folly::StringPiece compilationDirectory); bool findAddress(uintptr_t address, Path& file, uint64_t& line); @@ -189,9 +199,9 @@ class Dwarf { // Execute until we commit one new row to the line number matrix bool next(folly::StringPiece& program); enum StepResult { - CONTINUE, // Continue feeding opcodes - COMMIT, // Commit new tuple - END, // End of sequence + CONTINUE, // Continue feeding opcodes + COMMIT, // Commit new tuple + END, // End of sequence }; // Execute one opcode StepResult step(folly::StringPiece& program); @@ -263,10 +273,8 @@ class Dwarf { // Read one attribute value, advance sp typedef boost::variant AttributeValue; - AttributeValue readAttributeValue( - folly::StringPiece& sp, - uint64_t form, - bool is64Bit) const; + AttributeValue + readAttributeValue(folly::StringPiece& sp, uint64_t form, bool is64Bit) const; // Get an ELF section by name, return true if found bool getSection(const char* name, folly::StringPiece* section) const; @@ -274,16 +282,16 @@ class Dwarf { // Get a string from the .debug_str section folly::StringPiece getStringFromStringSection(uint64_t offset) const; - folly::StringPiece info_; // .debug_info - folly::StringPiece abbrev_; // .debug_abbrev - folly::StringPiece aranges_; // .debug_aranges - folly::StringPiece line_; // .debug_line - folly::StringPiece strings_; // .debug_str + folly::StringPiece info_; // .debug_info + folly::StringPiece abbrev_; // .debug_abbrev + folly::StringPiece aranges_; // .debug_aranges + folly::StringPiece line_; // .debug_line + folly::StringPiece strings_; // .debug_str }; inline std::ostream& operator<<(std::ostream& out, const Dwarf::Path& path) { return out << path.toString(); } -} // namespace symbolizer -} // namespace folly +} // namespace symbolizer +} // namespace folly diff --git a/folly/experimental/symbolizer/Elf-inl.h b/folly/experimental/symbolizer/Elf-inl.h index e643dd2f..1679f5c7 100644 --- a/folly/experimental/symbolizer/Elf-inl.h +++ b/folly/experimental/symbolizer/Elf-inl.h @@ -14,17 +14,16 @@ * limitations under the License. */ - #ifndef FOLLY_EXPERIMENTAL_SYMBOLIZER_ELF_H_ -# error This file must be included from Elf.h +#error This file must be included from Elf.h #endif namespace folly { namespace symbolizer { template -const ElfW(Shdr)* ElfFile::iterateSections(Fn fn) const { - const ElfW(Shdr)* ptr = &at(elfHeader().e_shoff); +const ElfShdr* ElfFile::iterateSections(Fn fn) const { + const ElfShdr* ptr = &at(elfHeader().e_shoff); for (size_t i = 0; i < elfHeader().e_shnum; i++, ptr++) { if (fn(*ptr)) { return ptr; @@ -35,17 +34,13 @@ const ElfW(Shdr)* ElfFile::iterateSections(Fn fn) const { } template -const ElfW(Shdr)* ElfFile::iterateSectionsWithType(uint32_t type, Fn fn) - const { +const ElfShdr* ElfFile::iterateSectionsWithType(uint32_t type, Fn fn) const { return iterateSections( - [&](const ElfW(Shdr)& sh) { - return sh.sh_type == type && fn(sh); - }); + [&](const ElfShdr& sh) { return sh.sh_type == type && fn(sh); }); } template -const char* ElfFile::iterateStrings(const ElfW(Shdr)& stringTable, Fn fn) - const { +const char* ElfFile::iterateStrings(const ElfShdr& stringTable, Fn fn) const { validateStringTable(stringTable); const char* start = file_ + stringTable.sh_offset; @@ -60,13 +55,13 @@ const char* ElfFile::iterateStrings(const ElfW(Shdr)& stringTable, Fn fn) } template -const ElfW(Sym)* ElfFile::iterateSymbols(const ElfW(Shdr)& section, Fn fn) - const { - FOLLY_SAFE_CHECK(section.sh_entsize == sizeof(ElfW(Sym)), - "invalid entry size in symbol table"); +const ElfSym* ElfFile::iterateSymbols(const ElfShdr& section, Fn fn) const { + FOLLY_SAFE_CHECK( + section.sh_entsize == sizeof(ElfSym), + "invalid entry size in symbol table"); - const ElfW(Sym)* sym = &at(section.sh_offset); - const ElfW(Sym)* end = sym + (section.sh_size / section.sh_entsize); + const ElfSym* sym = &at(section.sh_offset); + const ElfSym* end = sym + (section.sh_size / section.sh_entsize); while (sym < end) { if (fn(*sym)) { @@ -80,13 +75,15 @@ const ElfW(Sym)* ElfFile::iterateSymbols(const ElfW(Shdr)& section, Fn fn) } template -const ElfW(Sym)* ElfFile::iterateSymbolsWithType(const ElfW(Shdr)& section, - uint32_t type, Fn fn) const { +const ElfSym* ElfFile::iterateSymbolsWithType( + const ElfShdr& section, + uint32_t type, + Fn fn) const { // N.B. st_info has the same representation on 32- and 64-bit platforms - return iterateSymbols(section, [&](const ElfW(Sym)& sym) -> bool { + return iterateSymbols(section, [&](const ElfSym& sym) -> bool { return ELF32_ST_TYPE(sym.st_info) == type && fn(sym); }); } -} // namespace symbolizer -} // namespace folly +} // namespace symbolizer +} // namespace folly diff --git a/folly/experimental/symbolizer/Elf.cpp b/folly/experimental/symbolizer/Elf.cpp index cc643866..038bea7a 100644 --- a/folly/experimental/symbolizer/Elf.cpp +++ b/folly/experimental/symbolizer/Elf.cpp @@ -32,17 +32,16 @@ namespace folly { namespace symbolizer { ElfFile::ElfFile() noexcept - : fd_(-1), - file_(static_cast(MAP_FAILED)), - length_(0), - baseAddress_(0) { -} + : fd_(-1), + file_(static_cast(MAP_FAILED)), + length_(0), + baseAddress_(0) {} ElfFile::ElfFile(const char* name, bool readOnly) - : fd_(-1), - file_(static_cast(MAP_FAILED)), - length_(0), - baseAddress_(0) { + : fd_(-1), + file_(static_cast(MAP_FAILED)), + length_(0), + baseAddress_(0) { open(name, readOnly); } @@ -56,23 +55,28 @@ void ElfFile::open(const char* name, bool readOnly) { } } -int ElfFile::openNoThrow(const char* name, - bool readOnly, - const char** msg) noexcept { +int ElfFile::openNoThrow( + const char* name, + bool readOnly, + const char** msg) noexcept { FOLLY_SAFE_CHECK(fd_ == -1, "File already open"); fd_ = ::open(name, readOnly ? O_RDONLY : O_RDWR); if (fd_ == -1) { - if (msg) *msg = "open"; + 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(); }); + ScopeGuard guard = makeGuard([&] { reset(); }); struct stat st; int r = fstat(fd_, &st); if (r == -1) { - if (msg) *msg = "fstat"; + if (msg) { + *msg = "fstat"; + } return kSystemError; } @@ -83,7 +87,9 @@ int ElfFile::openNoThrow(const char* name, } file_ = static_cast(mmap(nullptr, length_, prot, MAP_SHARED, fd_, 0)); if (file_ == MAP_FAILED) { - if (msg) *msg = "mmap"; + if (msg) { + *msg = "mmap"; + } return kSystemError; } if (!init(msg)) { @@ -94,11 +100,14 @@ int ElfFile::openNoThrow(const char* name, return kSuccess; } -int ElfFile::openAndFollow(const char* name, - bool readOnly, - const char** msg) noexcept { +int ElfFile::openAndFollow( + const char* name, + bool readOnly, + const char** msg) noexcept { auto result = openNoThrow(name, readOnly, msg); - if (!readOnly || result != kSuccess) return result; + if (!readOnly || result != kSuccess) { + return result; + } /* NOTE .gnu_debuglink specifies only the name of the debugging info file * (with no directory components). GDB checks 3 different directories, but @@ -112,7 +121,9 @@ int ElfFile::openAndFollow(const char* name, auto dirlen = dirend != nullptr ? dirend + 1 - name : 0; auto debuginfo = getSectionByName(".gnu_debuglink"); - if (!debuginfo) return result; + if (!debuginfo) { + return result; + } // The section starts with the filename, with any leading directory // components removed, followed by a zero byte. @@ -127,7 +138,9 @@ int ElfFile::openAndFollow(const char* name, memcpy(linkname + dirlen, debugFileName.begin(), debugFileLen + 1); reset(); result = openNoThrow(linkname, readOnly, msg); - if (result == kSuccess) return result; + if (result == kSuccess) { + return result; + } return openNoThrow(name, readOnly, msg); } @@ -136,10 +149,10 @@ ElfFile::~ElfFile() { } ElfFile::ElfFile(ElfFile&& other) noexcept - : fd_(other.fd_), - file_(other.file_), - length_(other.length_), - baseAddress_(other.baseAddress_) { + : fd_(other.fd_), + file_(other.file_), + length_(other.length_), + baseAddress_(other.baseAddress_) { other.fd_ = -1; other.file_ = static_cast(MAP_FAILED); other.length_ = 0; @@ -183,16 +196,20 @@ bool ElfFile::init(const char** msg) { elfHeader.e_ident[EI_MAG1] == ELFMAG1 && elfHeader.e_ident[EI_MAG2] == ELFMAG2 && elfHeader.e_ident[EI_MAG3] == ELFMAG3)) { - if (msg) *msg = "invalid ELF magic"; + if (msg) { + *msg = "invalid ELF magic"; + } return false; } - // Validate ELF class (32/64 bits) #define EXPECTED_CLASS P1(ELFCLASS, __ELF_NATIVE_CLASS) #define P1(a, b) P2(a, b) -#define P2(a, b) a ## b +#define P2(a, b) a##b + // Validate ELF class (32/64 bits) if (elfHeader.e_ident[EI_CLASS] != EXPECTED_CLASS) { - if (msg) *msg = "invalid ELF class"; + if (msg) { + *msg = "invalid ELF class"; + } return false; } #undef P1 @@ -203,38 +220,50 @@ bool ElfFile::init(const char** msg) { static constexpr auto kExpectedEncoding = kIsLittleEndian ? ELFDATA2LSB : ELFDATA2MSB; if (elfHeader.e_ident[EI_DATA] != kExpectedEncoding) { - if (msg) *msg = "invalid ELF encoding"; + if (msg) { + *msg = "invalid ELF encoding"; + } return false; } // Validate ELF version (1) if (elfHeader.e_ident[EI_VERSION] != EV_CURRENT || elfHeader.e_version != EV_CURRENT) { - if (msg) *msg = "invalid ELF version"; + if (msg) { + *msg = "invalid ELF version"; + } return false; } // We only support executable and shared object files if (elfHeader.e_type != ET_EXEC && elfHeader.e_type != ET_DYN) { - if (msg) *msg = "invalid ELF file type"; + if (msg) { + *msg = "invalid ELF file type"; + } return false; } if (elfHeader.e_phnum == 0) { - if (msg) *msg = "no program header!"; + if (msg) { + *msg = "no program header!"; + } return false; } - if (elfHeader.e_phentsize != sizeof(ElfW(Phdr))) { - if (msg) *msg = "invalid program header entry size"; + if (elfHeader.e_phentsize != sizeof(ElfPhdr)) { + if (msg) { + *msg = "invalid program header entry size"; + } return false; } - if (elfHeader.e_shentsize != sizeof(ElfW(Shdr))) { - if (msg) *msg = "invalid section header entry size"; + if (elfHeader.e_shentsize != sizeof(ElfShdr)) { + if (msg) { + *msg = "invalid section header entry size"; + } } - const ElfW(Phdr)* programHeader = &at(elfHeader.e_phoff); + const ElfPhdr* programHeader = &at(elfHeader.e_phoff); bool foundBase = false; for (size_t i = 0; i < elfHeader.e_phnum; programHeader++, i++) { // Program headers are sorted by load address, so the first PT_LOAD @@ -247,61 +276,63 @@ bool ElfFile::init(const char** msg) { } if (!foundBase) { - if (msg) *msg = "could not find base address"; + if (msg) { + *msg = "could not find base address"; + } return false; } return true; } -const ElfW(Shdr)* ElfFile::getSectionByIndex(size_t idx) const { +const ElfShdr* ElfFile::getSectionByIndex(size_t idx) const { FOLLY_SAFE_CHECK(idx < elfHeader().e_shnum, "invalid section index"); - return &at(elfHeader().e_shoff + idx * sizeof(ElfW(Shdr))); + return &at(elfHeader().e_shoff + idx * sizeof(ElfShdr)); } -folly::StringPiece ElfFile::getSectionBody(const ElfW(Shdr)& section) const { +folly::StringPiece ElfFile::getSectionBody(const ElfShdr& section) const { return folly::StringPiece(file_ + section.sh_offset, section.sh_size); } -void ElfFile::validateStringTable(const ElfW(Shdr)& stringTable) const { - FOLLY_SAFE_CHECK(stringTable.sh_type == SHT_STRTAB, - "invalid type for string table"); +void ElfFile::validateStringTable(const ElfShdr& stringTable) const { + FOLLY_SAFE_CHECK( + stringTable.sh_type == SHT_STRTAB, "invalid type for string table"); const char* start = file_ + stringTable.sh_offset; // First and last bytes must be 0 - FOLLY_SAFE_CHECK(stringTable.sh_size == 0 || - (start[0] == '\0' && start[stringTable.sh_size - 1] == '\0'), - "invalid string table"); + FOLLY_SAFE_CHECK( + stringTable.sh_size == 0 || + (start[0] == '\0' && start[stringTable.sh_size - 1] == '\0'), + "invalid string table"); } -const char* ElfFile::getString(const ElfW(Shdr)& stringTable, size_t offset) - const { +const char* ElfFile::getString(const ElfShdr& stringTable, size_t offset) + const { validateStringTable(stringTable); - FOLLY_SAFE_CHECK(offset < stringTable.sh_size, - "invalid offset in string table"); + FOLLY_SAFE_CHECK( + offset < stringTable.sh_size, "invalid offset in string table"); return file_ + stringTable.sh_offset + offset; } -const char* ElfFile::getSectionName(const ElfW(Shdr)& section) const { +const char* ElfFile::getSectionName(const ElfShdr& section) const { if (elfHeader().e_shstrndx == SHN_UNDEF) { - return nullptr; // no section name string table + return nullptr; // no section name string table } - const ElfW(Shdr)& sectionNames = *getSectionByIndex(elfHeader().e_shstrndx); + const ElfShdr& sectionNames = *getSectionByIndex(elfHeader().e_shstrndx); return getString(sectionNames, section.sh_name); } -const ElfW(Shdr)* ElfFile::getSectionByName(const char* name) const { +const ElfShdr* ElfFile::getSectionByName(const char* name) const { if (elfHeader().e_shstrndx == SHN_UNDEF) { - return nullptr; // no section name string table + return nullptr; // no section name string table } // Find offset in the section name string table of the requested name - const ElfW(Shdr)& sectionNames = *getSectionByIndex(elfHeader().e_shstrndx); + const ElfShdr& sectionNames = *getSectionByIndex(elfHeader().e_shstrndx); const char* foundName = iterateStrings( - sectionNames, - [&] (const char* s) { return !strcmp(name, s); }); + sectionNames, [&](const char* s) { return !strcmp(name, s); }); if (foundName == nullptr) { return nullptr; } @@ -309,23 +340,22 @@ const ElfW(Shdr)* ElfFile::getSectionByName(const char* name) const { size_t offset = foundName - (file_ + sectionNames.sh_offset); // Find section with the appropriate sh_name offset - const ElfW(Shdr)* foundSection = iterateSections( - [&](const ElfW(Shdr)& sh) { - if (sh.sh_name == offset) { - return true; - } - return false; - }); + const ElfShdr* foundSection = iterateSections([&](const ElfShdr& sh) { + if (sh.sh_name == offset) { + return true; + } + return false; + }); return foundSection; } ElfFile::Symbol ElfFile::getDefinitionByAddress(uintptr_t address) const { - Symbol foundSymbol {nullptr, nullptr}; + Symbol foundSymbol{nullptr, nullptr}; - auto findSection = [&](const ElfW(Shdr)& section) { - auto findSymbols = [&](const ElfW(Sym)& sym) { + auto findSection = [&](const ElfShdr& section) { + auto findSymbols = [&](const ElfSym& sym) { if (sym.st_shndx == SHN_UNDEF) { - return false; // not a definition + return false; // not a definition } if (address >= sym.st_value && address < sym.st_value + sym.st_size) { foundSymbol.first = §ion; @@ -337,7 +367,7 @@ ElfFile::Symbol ElfFile::getDefinitionByAddress(uintptr_t address) const { }; return iterateSymbolsWithType(section, STT_OBJECT, findSymbols) || - iterateSymbolsWithType(section, STT_FUNC, findSymbols); + iterateSymbolsWithType(section, STT_FUNC, findSymbols); }; // Try the .dynsym section first if it exists, it's smaller. @@ -350,22 +380,22 @@ ElfFile::Symbol ElfFile::getDefinitionByAddress(uintptr_t address) const { ElfFile::Symbol ElfFile::getSymbolByName(const char* name) const { Symbol foundSymbol{nullptr, nullptr}; - auto findSection = [&](const ElfW(Shdr)& section) -> bool { + auto findSection = [&](const ElfShdr& section) -> bool { // This section has no string table associated w/ its symbols; hence we // can't get names for them if (section.sh_link == SHN_UNDEF) { return false; } - auto findSymbols = [&](const ElfW(Sym)& sym) -> bool { + auto findSymbols = [&](const ElfSym& sym) -> bool { if (sym.st_shndx == SHN_UNDEF) { - return false; // not a definition + return false; // not a definition } if (sym.st_name == 0) { - return false; // no name for this symbol + return false; // no name for this symbol } - const char* sym_name = getString( - *getSectionByIndex(section.sh_link), sym.st_name); + const char* sym_name = + getString(*getSectionByIndex(section.sh_link), sym.st_name); if (strcmp(sym_name, name) == 0) { foundSymbol.first = §ion; foundSymbol.second = &sym; @@ -376,18 +406,18 @@ ElfFile::Symbol ElfFile::getSymbolByName(const char* name) const { }; return iterateSymbolsWithType(section, STT_OBJECT, findSymbols) || - iterateSymbolsWithType(section, STT_FUNC, findSymbols); + iterateSymbolsWithType(section, STT_FUNC, findSymbols); }; // Try the .dynsym section first if it exists, it's smaller. iterateSectionsWithType(SHT_DYNSYM, findSection) || - iterateSectionsWithType(SHT_SYMTAB, findSection); + iterateSectionsWithType(SHT_SYMTAB, findSection); return foundSymbol; } -const ElfW(Shdr)* ElfFile::getSectionContainingAddress(ElfW(Addr) addr) const { - return iterateSections([&](const ElfW(Shdr)& sh) -> bool { +const ElfShdr* ElfFile::getSectionContainingAddress(ElfAddr addr) const { + return iterateSections([&](const ElfShdr& sh) -> bool { return (addr >= sh.sh_addr) && (addr < (sh.sh_addr + sh.sh_size)); }); } @@ -398,16 +428,16 @@ const char* ElfFile::getSymbolName(Symbol symbol) const { } if (symbol.second->st_name == 0) { - return nullptr; // symbol has no name + return nullptr; // symbol has no name } if (symbol.first->sh_link == SHN_UNDEF) { - return nullptr; // symbol table has no strings + return nullptr; // symbol table has no strings } - return getString(*getSectionByIndex(symbol.first->sh_link), - symbol.second->st_name); + return getString( + *getSectionByIndex(symbol.first->sh_link), symbol.second->st_name); } -} // namespace symbolizer -} // namespace folly +} // namespace symbolizer +} // namespace folly diff --git a/folly/experimental/symbolizer/Elf.h b/folly/experimental/symbolizer/Elf.h index f0a0bd7b..48b5f8fb 100644 --- a/folly/experimental/symbolizer/Elf.h +++ b/folly/experimental/symbolizer/Elf.h @@ -34,6 +34,13 @@ namespace folly { namespace symbolizer { +using ElfAddr = ElfW(Addr); +using ElfEhdr = ElfW(Ehdr); +using ElfOff = ElfW(Off); +using ElfPhdr = ElfW(Phdr); +using ElfShdr = ElfW(Shdr); +using ElfSym = ElfW(Sym); + /** * ELF file parser. * @@ -46,7 +53,7 @@ class ElfFile { ElfFile() noexcept; // Note: may throw, call openNoThrow() explicitly if you don't want to throw - explicit ElfFile(const char* name, bool readOnly=true); + explicit ElfFile(const char* name, bool readOnly = true); // Open the ELF file. // Returns 0 on success, kSystemError (guaranteed to be -1) (and sets errno) @@ -59,15 +66,19 @@ class ElfFile { kInvalidElfFile = -2, }; // Open the ELF file. Does not throw on error. - int openNoThrow(const char* name, bool readOnly=true, - const char** msg=nullptr) noexcept; + int openNoThrow( + const char* name, + bool readOnly = true, + const char** msg = nullptr) noexcept; // Like openNoThrow, but follow .gnu_debuglink if present - int openAndFollow(const char* name, bool readOnly=true, - const char** msg=nullptr) noexcept; + int openAndFollow( + const char* name, + bool readOnly = true, + const char** msg = nullptr) noexcept; // Open the ELF file. Throws on error. - void open(const char* name, bool readOnly=true); + void open(const char* name, bool readOnly = true); ~ElfFile(); @@ -75,8 +86,8 @@ class ElfFile { ElfFile& operator=(ElfFile&& other); /** Retrieve the ELF header */ - const ElfW(Ehdr)& elfHeader() const { - return at(0); + const ElfEhdr& elfHeader() const { + return at(0); } /** @@ -88,19 +99,19 @@ class ElfFile { } /** Find a section given its name */ - const ElfW(Shdr)* getSectionByName(const char* name) const; + const ElfShdr* getSectionByName(const char* name) const; /** Find a section given its index in the section header table */ - const ElfW(Shdr)* getSectionByIndex(size_t idx) const; + const ElfShdr* getSectionByIndex(size_t idx) const; /** Retrieve the name of a section */ - const char* getSectionName(const ElfW(Shdr)& section) const; + const char* getSectionName(const ElfShdr& section) const; /** Get the actual section body */ - folly::StringPiece getSectionBody(const ElfW(Shdr)& section) const; + folly::StringPiece getSectionBody(const ElfShdr& section) const; /** Retrieve a string from a string table section */ - const char* getString(const ElfW(Shdr)& stringTable, size_t offset) const; + const char* getString(const ElfShdr& stringTable, size_t offset) const; /** * Iterate over all strings in a string table section for as long as @@ -109,7 +120,7 @@ class ElfFile { * if fn returned false for all strings in the table. */ template - const char* iterateStrings(const ElfW(Shdr)& stringTable, Fn fn) const; + const char* iterateStrings(const ElfShdr& stringTable, Fn fn) const; /** * Iterate over all sections for as long as fn(section) returns false. @@ -117,14 +128,14 @@ class ElfFile { * true, or nullptr if fn returned false for all sections. */ template - const ElfW(Shdr)* iterateSections(Fn fn) const; + const ElfShdr* iterateSections(Fn fn) const; /** * Iterate over all sections with a given type. Similar to * iterateSections(), but filtered only for sections with the given type. */ template - const ElfW(Shdr)* iterateSectionsWithType(uint32_t type, Fn fn) const; + const ElfShdr* iterateSectionsWithType(uint32_t type, Fn fn) const; /** * Iterate over all symbols witin a given section. @@ -133,10 +144,10 @@ class ElfFile { * or nullptr if fn returned false for all symbols. */ template - const ElfW(Sym)* iterateSymbols(const ElfW(Shdr)& section, Fn fn) const; + const ElfSym* iterateSymbols(const ElfShdr& section, Fn fn) const; template - const ElfW(Sym)* iterateSymbolsWithType(const ElfW(Shdr)& section, - uint32_t type, Fn fn) const; + const ElfSym* + iterateSymbolsWithType(const ElfShdr& section, uint32_t type, Fn fn) const; /** * Find symbol definition by address. @@ -145,7 +156,7 @@ class ElfFile { * * Returns {nullptr, nullptr} if not found. */ - typedef std::pair Symbol; + typedef std::pair Symbol; Symbol getDefinitionByAddress(uintptr_t address) const; /** @@ -162,8 +173,8 @@ class ElfFile { * Get the value of a symbol. */ template - const T& getSymbolValue(const ElfW(Sym)* symbol) const { - const ElfW(Shdr)* section = getSectionByIndex(symbol->st_shndx); + const T& getSymbolValue(const ElfSym* symbol) const { + const ElfShdr* section = getSectionByIndex(symbol->st_shndx); FOLLY_SAFE_CHECK(section, "Symbol's section index is invalid"); return valueAt(*section, symbol->st_value); @@ -177,12 +188,12 @@ class ElfFile { * a char* symbol, you'd do something like this: * * auto sym = getSymbolByName("someGlobalValue"); - * auto addr = getSymbolValue(sym.second); + * auto addr = getSymbolValue(sym.second); * const char* str = &getSymbolValue(addr); */ template - const T& getAddressValue(const ElfW(Addr) addr) const { - const ElfW(Shdr)* section = getSectionContainingAddress(addr); + const T& getAddressValue(const ElfAddr addr) const { + const ElfShdr* section = getSectionContainingAddress(addr); FOLLY_SAFE_CHECK(section, "Address does not refer to existing section"); return valueAt(*section, addr); @@ -194,7 +205,7 @@ class ElfFile { const char* getSymbolName(Symbol symbol) const; /** Find the section containing the given address */ - const ElfW(Shdr)* getSectionContainingAddress(ElfW(Addr) addr) const; + const ElfShdr* getSectionContainingAddress(ElfAddr addr) const; private: bool init(const char** msg); @@ -202,19 +213,20 @@ class ElfFile { ElfFile(const ElfFile&) = delete; ElfFile& operator=(const ElfFile&) = delete; - void validateStringTable(const ElfW(Shdr)& stringTable) const; + void validateStringTable(const ElfShdr& stringTable) const; template - const typename std::enable_if::value, T>::type& - at(ElfW(Off) offset) const { - FOLLY_SAFE_CHECK(offset + sizeof(T) <= length_, - "Offset is not contained within our mmapped file"); + const typename std::enable_if::value, T>::type& at( + ElfOff offset) const { + FOLLY_SAFE_CHECK( + offset + sizeof(T) <= length_, + "Offset is not contained within our mmapped file"); return *reinterpret_cast(file_ + offset); } template - const T& valueAt(const ElfW(Shdr)& section, const ElfW(Addr) addr) const { + const T& valueAt(const ElfShdr& section, const ElfAddr addr) const { // For exectuables and shared objects, st_value holds a virtual address // that refers to the memory owned by sections. Since we didn't map the // sections into the addresses that they're expecting (sh_addr), but @@ -229,20 +241,20 @@ class ElfFile { "Only exectuables and shared objects are supported"); FOLLY_SAFE_CHECK( addr >= section.sh_addr && - (addr + sizeof(T)) <= (section.sh_addr + section.sh_size), + (addr + sizeof(T)) <= (section.sh_addr + section.sh_size), "Address is not contained within the provided segment"); return at(section.sh_offset + (addr - section.sh_addr)); } int fd_; - char* file_; // mmap() location - size_t length_; // mmap() length + char* file_; // mmap() location + size_t length_; // mmap() length uintptr_t baseAddress_; }; -} // namespace symbolizer -} // namespace folly +} // namespace symbolizer +} // namespace folly #include diff --git a/folly/experimental/symbolizer/ElfCache.cpp b/folly/experimental/symbolizer/ElfCache.cpp index 5bdd0756..24af7721 100644 --- a/folly/experimental/symbolizer/ElfCache.cpp +++ b/folly/experimental/symbolizer/ElfCache.cpp @@ -26,7 +26,8 @@ */ extern struct r_debug _r_debug; -namespace folly { namespace symbolizer { +namespace folly { +namespace symbolizer { size_t countLoadedElfFiles() { // _r_debug synchronization is... lacking to say the least. It's @@ -88,7 +89,7 @@ std::shared_ptr SignalSafeElfCache::getFile(StringPiece p) { return f; } -ElfCache::ElfCache(size_t capacity) : capacity_(capacity) { } +ElfCache::ElfCache(size_t capacity) : capacity_(capacity) {} std::shared_ptr ElfCache::getFile(StringPiece p) { std::lock_guard lock(mutex_); @@ -129,5 +130,5 @@ std::shared_ptr ElfCache::filePtr(const std::shared_ptr& e) { // share ownership return std::shared_ptr(e, &e->file); } - -}} // namespaces +} // namespace symbolizer +} // namespace folly diff --git a/folly/experimental/symbolizer/ElfCache.h b/folly/experimental/symbolizer/ElfCache.h index af4f4c44..b9d7d966 100644 --- a/folly/experimental/symbolizer/ElfCache.h +++ b/folly/experimental/symbolizer/ElfCache.h @@ -33,7 +33,8 @@ #include #include -namespace folly { namespace symbolizer { +namespace folly { +namespace symbolizer { /** * Number of ELF files loaded by the dynamic loader. @@ -43,7 +44,7 @@ size_t countLoadedElfFiles(); class ElfCacheBase { public: virtual std::shared_ptr getFile(StringPiece path) = 0; - virtual ~ElfCacheBase() { } + virtual ~ElfCacheBase() {} }; /** @@ -139,8 +140,9 @@ class ElfCache : public ElfCacheBase { typedef boost::intrusive::list< Entry, boost::intrusive::member_hook, - boost::intrusive::constant_time_size> LruList; + boost::intrusive::constant_time_size> + LruList; LruList lruList_; }; - -}} // namespaces +} // namespace symbolizer +} // namespace folly diff --git a/folly/experimental/symbolizer/ElfUtil.cpp b/folly/experimental/symbolizer/ElfUtil.cpp index fc45bef8..e9ebfbb9 100644 --- a/folly/experimental/symbolizer/ElfUtil.cpp +++ b/folly/experimental/symbolizer/ElfUtil.cpp @@ -14,7 +14,6 @@ * limitations under the License. */ - #include #include @@ -26,7 +25,7 @@ using namespace folly; using namespace folly::symbolizer; -int main(int argc, char *argv[]) { +int main(int argc, char* argv[]) { gflags::ParseCommandLineFlags(&argc, &argv, true); CHECK_GE(argc, 2); @@ -34,9 +33,7 @@ int main(int argc, char *argv[]) { if (argc > 2) { auto section = elf.getSectionByName(argv[2]); - printf("Section %s: %s\n", - argv[2], - (section ? "found" : "not found")); + printf("Section %s: %s\n", argv[2], (section ? "found" : "not found")); } auto sym = elf.getDefinitionByAddress(reinterpret_cast(main)); diff --git a/folly/experimental/symbolizer/LineReader.cpp b/folly/experimental/symbolizer/LineReader.cpp index 3c824fd0..7612c445 100644 --- a/folly/experimental/symbolizer/LineReader.cpp +++ b/folly/experimental/symbolizer/LineReader.cpp @@ -20,20 +20,20 @@ #include -namespace folly { namespace symbolizer { +namespace folly { +namespace symbolizer { LineReader::LineReader(int fd, char* buf, size_t bufSize) - : fd_(fd), - buf_(buf), - bufEnd_(buf_ + bufSize), - bol_(buf), - eol_(buf), - end_(buf), - state_(kReading) { -} + : fd_(fd), + buf_(buf), + bufEnd_(buf_ + bufSize), + bol_(buf), + eol_(buf), + end_(buf), + state_(kReading) {} LineReader::State LineReader::readLine(StringPiece& line) { - bol_ = eol_; // Start past what we already returned + bol_ = eol_; // Start past what we already returned for (;;) { // Search for newline char* newline = static_cast(memchr(eol_, '\n', end_ - eol_)); @@ -69,5 +69,5 @@ LineReader::State LineReader::readLine(StringPiece& line) { line.assign(bol_, eol_); return eol_ != bol_ ? kReading : state_; } - -}} // namespaces +} // namespace symbolizer +} // namespace folly diff --git a/folly/experimental/symbolizer/LineReader.h b/folly/experimental/symbolizer/LineReader.h index 85c8943c..45eae73d 100644 --- a/folly/experimental/symbolizer/LineReader.h +++ b/folly/experimental/symbolizer/LineReader.h @@ -22,7 +22,8 @@ #include -namespace folly { namespace symbolizer { +namespace folly { +namespace symbolizer { /** * Async-signal-safe line reader. @@ -38,7 +39,7 @@ class LineReader : private boost::noncopyable { enum State { kReading, kEof, - kError + kError, }; /** * Read the next line from the file. @@ -83,5 +84,5 @@ class LineReader : private boost::noncopyable { char* end_; State state_; }; - -}} // namespaces +} // namespace symbolizer +} // namespace folly diff --git a/folly/experimental/symbolizer/SignalHandler.cpp b/folly/experimental/symbolizer/SignalHandler.cpp index ccc7bd18..bcd5b51e 100644 --- a/folly/experimental/symbolizer/SignalHandler.cpp +++ b/folly/experimental/symbolizer/SignalHandler.cpp @@ -37,7 +37,8 @@ #include #include -namespace folly { namespace symbolizer { +namespace folly { +namespace symbolizer { namespace { @@ -59,22 +60,20 @@ class FatalSignalCallbackRegistry { }; FatalSignalCallbackRegistry::FatalSignalCallbackRegistry() - : installed_(false) { -} + : installed_(false) {} void FatalSignalCallbackRegistry::add(SignalCallback func) { std::lock_guard lock(mutex_); - CHECK(!installed_) - << "FatalSignalCallbackRegistry::add may not be used " - "after installing the signal handlers."; + CHECK(!installed_) << "FatalSignalCallbackRegistry::add may not be used " + "after installing the signal handlers."; handlers_.push_back(func); } void FatalSignalCallbackRegistry::markInstalled() { std::lock_guard lock(mutex_); CHECK(!installed_.exchange(true)) - << "FatalSignalCallbackRegistry::markInstalled must be called " - << "at most once"; + << "FatalSignalCallbackRegistry::markInstalled must be called " + << "at most once"; } void FatalSignalCallbackRegistry::run() { @@ -89,20 +88,20 @@ void FatalSignalCallbackRegistry::run() { // Leak it so we don't have to worry about destruction order FatalSignalCallbackRegistry* gFatalSignalCallbackRegistry = - new FatalSignalCallbackRegistry; + new FatalSignalCallbackRegistry; struct { int number; const char* name; struct sigaction oldAction; } kFatalSignals[] = { - { SIGSEGV, "SIGSEGV", {} }, - { SIGILL, "SIGILL", {} }, - { SIGFPE, "SIGFPE", {} }, - { SIGABRT, "SIGABRT", {} }, - { SIGBUS, "SIGBUS", {} }, - { SIGTERM, "SIGTERM", {} }, - { 0, nullptr, {} } + {SIGSEGV, "SIGSEGV", {}}, + {SIGILL, "SIGILL", {}}, + {SIGFPE, "SIGFPE", {}}, + {SIGABRT, "SIGABRT", {}}, + {SIGBUS, "SIGBUS", {}}, + {SIGTERM, "SIGTERM", {}}, + {0, nullptr, {}}, }; void callPreviousSignalHandler(int signum) { @@ -140,7 +139,7 @@ void printDec(uint64_t val) { const char kHexChars[] = "0123456789abcdef"; void printHex(uint64_t val) { // TODO(tudorb): Add this to folly/Conv.h - char buf[2 + 2 * sizeof(uint64_t)]; // "0x" prefix, 2 digits for each byte + char buf[2 + 2 * sizeof(uint64_t)]; // "0x" prefix, 2 digits for each byte char* end = buf + sizeof(buf); char* p = end; @@ -163,7 +162,9 @@ void flush() { } void dumpTimeInfo() { - SCOPE_EXIT { flush(); }; + SCOPE_EXIT { + flush(); + }; time_t now = time(nullptr); print("*** Aborted at "); printDec(now); @@ -325,7 +326,9 @@ const char* signal_reason(int signum, int si_code) { } void dumpSignalInfo(int signum, siginfo_t* siginfo) { - SCOPE_EXIT { flush(); }; + SCOPE_EXIT { + flush(); + }; // Get the signal name, if possible. const char* name = nullptr; for (auto p = kFatalSignals; p->name; ++p) { @@ -400,7 +403,7 @@ void innerSignalHandler(int signum, siginfo_t* info, void* /* uctx */) { // Wait a while, try again. timespec ts; ts.tv_sec = 0; - ts.tv_nsec = 100L * 1000 * 1000; // 100ms + ts.tv_nsec = 100L * 1000 * 1000; // 100ms nanosleep(&ts, nullptr); prevSignalThread = kInvalidThreadId; @@ -415,7 +418,9 @@ void innerSignalHandler(int signum, siginfo_t* info, void* /* uctx */) { } void signalHandler(int signum, siginfo_t* info, void* uctx) { - SCOPE_EXIT { flush(); }; + SCOPE_EXIT { + flush(); + }; innerSignalHandler(signum, info, uctx); gSignalThread = kInvalidThreadId; @@ -423,7 +428,7 @@ void signalHandler(int signum, siginfo_t* info, void* uctx) { callPreviousSignalHandler(signum); } -} // namespace +} // namespace void addFatalSignalCallback(SignalCallback cb) { gFatalSignalCallbackRegistry->add(cb); @@ -437,7 +442,7 @@ namespace { std::atomic gAlreadyInstalled; -} // namespace +} // namespace void installFatalSignalHandler() { if (gAlreadyInstalled.exchange(true)) { @@ -460,5 +465,5 @@ void installFatalSignalHandler() { CHECK_ERR(sigaction(p->number, &sa, &p->oldAction)); } } - -}} // namespaces +} // namespace symbolizer +} // namespace folly diff --git a/folly/experimental/symbolizer/SignalHandler.h b/folly/experimental/symbolizer/SignalHandler.h index 6b748207..ae68fd59 100644 --- a/folly/experimental/symbolizer/SignalHandler.h +++ b/folly/experimental/symbolizer/SignalHandler.h @@ -18,7 +18,8 @@ #include -namespace folly { namespace symbolizer { +namespace folly { +namespace symbolizer { /** * Install handler for fatal signals. The list of signals being handled is in @@ -47,5 +48,5 @@ void addFatalSignalCallback(SignalCallback callback); * callbacks in the order in which they were added. */ void installFatalSignalCallbacks(); - -}} // namespaces +} // namespace symbolizer +} // namespace folly diff --git a/folly/experimental/symbolizer/StackTrace.cpp b/folly/experimental/symbolizer/StackTrace.cpp index 33e54de2..c58af4a7 100644 --- a/folly/experimental/symbolizer/StackTrace.cpp +++ b/folly/experimental/symbolizer/StackTrace.cpp @@ -20,11 +20,12 @@ #define UNW_LOCAL_ONLY 1 #include -namespace folly { namespace symbolizer { +namespace folly { +namespace symbolizer { ssize_t getStackTrace(uintptr_t* addresses, size_t maxAddresses) { - static_assert(sizeof(uintptr_t) == sizeof(void*), - "uinptr_t / pointer size mismatch"); + static_assert( + sizeof(uintptr_t) == sizeof(void*), "uinptr_t / pointer size mismatch"); // The libunwind documentation says that unw_backtrace is async-signal-safe // but, as of libunwind 1.0.1, it isn't (tdep_trace allocates memory on // x86_64) @@ -48,7 +49,7 @@ inline bool getFrameInfo(unw_cursor_t* cursor, uintptr_t& ip) { ip = uip - (r == 0); return true; } -} // namespace +} // namespace ssize_t getStackTraceSafe(uintptr_t* addresses, size_t maxAddresses) { if (maxAddresses == 0) { @@ -81,5 +82,5 @@ ssize_t getStackTraceSafe(uintptr_t* addresses, size_t maxAddresses) { } return count; } - -}} // namespaces +} // namespace symbolizer +} // namespace folly diff --git a/folly/experimental/symbolizer/StackTrace.h b/folly/experimental/symbolizer/StackTrace.h index 9d7220a4..a77bae7b 100644 --- a/folly/experimental/symbolizer/StackTrace.h +++ b/folly/experimental/symbolizer/StackTrace.h @@ -19,7 +19,8 @@ #include #include -namespace folly { namespace symbolizer { +namespace folly { +namespace symbolizer { /** * Get the current stack trace into addresses, which has room for at least @@ -42,5 +43,5 @@ ssize_t getStackTrace(uintptr_t* addresses, size_t maxAddresses); * Async-signal-safe, but likely slower. */ ssize_t getStackTraceSafe(uintptr_t* addresses, size_t maxAddresses); - -}} // namespaces +} // namespace symbolizer +} // namespace folly diff --git a/folly/experimental/symbolizer/Symbolizer.cpp b/folly/experimental/symbolizer/Symbolizer.cpp index 8c7183e2..96030510 100644 --- a/folly/experimental/symbolizer/Symbolizer.cpp +++ b/folly/experimental/symbolizer/Symbolizer.cpp @@ -58,11 +58,12 @@ ElfCache* defaultElfCache() { return cache; } -} // namespace +} // namespace -void SymbolizedFrame::set(const std::shared_ptr& file, - uintptr_t address, - Dwarf::LocationInfoMode mode) { +void SymbolizedFrame::set( + const std::shared_ptr& file, + uintptr_t address, + Dwarf::LocationInfoMode mode) { clear(); found = true; @@ -79,12 +80,12 @@ void SymbolizedFrame::set(const std::shared_ptr& file, } Symbolizer::Symbolizer(ElfCacheBase* cache, Dwarf::LocationInfoMode mode) - : cache_(cache ? cache : defaultElfCache()), mode_(mode) { -} + : cache_(cache ? cache : defaultElfCache()), mode_(mode) {} -void Symbolizer::symbolize(const uintptr_t* addresses, - SymbolizedFrame* frames, - size_t addrCount) { +void Symbolizer::symbolize( + const uintptr_t* addresses, + SymbolizedFrame* frames, + size_t addrCount) { size_t remaining = 0; for (size_t i = 0; i < addrCount; ++i) { auto& frame = frames[i]; @@ -94,7 +95,7 @@ void Symbolizer::symbolize(const uintptr_t* addresses, } } - if (remaining == 0) { // we're done + if (remaining == 0) { // we're done return; } @@ -110,8 +111,7 @@ void Symbolizer::symbolize(const uintptr_t* addresses, } selfPath[selfSize] = '\0'; - for (auto lmap = _r_debug.r_map; - lmap != nullptr && remaining != 0; + for (auto lmap = _r_debug.r_map; lmap != nullptr && remaining != 0; lmap = lmap->l_next) { // The empty string is used in place of the filename for the link_map // corresponding to the running executable. Additionally, the `l_addr' is @@ -129,9 +129,8 @@ void Symbolizer::symbolize(const uintptr_t* addresses, // header for the running executable, since its `l_addr' is zero, but we // should use `l_addr' for everything else---in particular, if the object // is position-independent, getBaseAddress() (which is p_vaddr) will be 0. - auto const base = lmap->l_addr != 0 - ? lmap->l_addr - : elfFile->getBaseAddress(); + auto const base = + lmap->l_addr != 0 ? lmap->l_addr : elfFile->getBaseAddress(); for (size_t i = 0; i < addrCount && remaining != 0; ++i) { auto& frame = frames[i]; @@ -156,7 +155,7 @@ constexpr char kHexChars[] = "0123456789abcdef"; constexpr auto kAddressColor = SymbolizePrinter::Color::BLUE; constexpr auto kFunctionColor = SymbolizePrinter::Color::PURPLE; constexpr auto kFileColor = SymbolizePrinter::Color::DEFAULT; -} // namespace +} // namespace constexpr char AddressFormatter::bufTemplate[]; constexpr std::array @@ -186,7 +185,9 @@ void SymbolizePrinter::print(uintptr_t address, const SymbolizedFrame& frame) { return; } - SCOPE_EXIT { color(Color::DEFAULT); }; + SCOPE_EXIT { + color(Color::DEFAULT); + }; if (!(options_ & NO_FRAME_ADDRESS)) { color(kAddressColor); @@ -196,8 +197,8 @@ void SymbolizePrinter::print(uintptr_t address, const SymbolizedFrame& frame) { } const char padBuf[] = " "; - folly::StringPiece pad(padBuf, - sizeof(padBuf) - 1 - (16 - 2 * sizeof(uintptr_t))); + folly::StringPiece pad( + padBuf, sizeof(padBuf) - 1 - (16 - 2 * sizeof(uintptr_t))); color(kFunctionColor); if (!frame.found) { @@ -245,8 +246,7 @@ void SymbolizePrinter::print(uintptr_t address, const SymbolizedFrame& frame) { } void SymbolizePrinter::color(SymbolizePrinter::Color color) { - if ((options_ & COLOR) == 0 && - ((options_ & COLOR_IF_TTY) == 0 || !isTty_)) { + if ((options_ & COLOR) == 0 && ((options_ & COLOR_IF_TTY) == 0 || !isTty_)) { return; } if (color < 0 || color >= kColorMap.size()) { @@ -255,14 +255,16 @@ void SymbolizePrinter::color(SymbolizePrinter::Color color) { doPrint(kColorMap[color]); } -void SymbolizePrinter::println(uintptr_t address, - const SymbolizedFrame& frame) { +void SymbolizePrinter::println( + uintptr_t address, + const SymbolizedFrame& frame) { print(address, frame); doPrint("\n"); } -void SymbolizePrinter::printTerse(uintptr_t address, - const SymbolizedFrame& frame) { +void SymbolizePrinter::printTerse( + uintptr_t address, + const SymbolizedFrame& frame) { if (frame.found && frame.name && frame.name[0] != '\0') { char demangledBuf[2048] = {0}; demangle(frame.name, demangledBuf, sizeof(demangledBuf)); @@ -282,9 +284,10 @@ void SymbolizePrinter::printTerse(uintptr_t address, } } -void SymbolizePrinter::println(const uintptr_t* addresses, - const SymbolizedFrame* frames, - size_t frameCount) { +void SymbolizePrinter::println( + const uintptr_t* addresses, + const SymbolizedFrame* frames, + size_t frameCount) { for (size_t i = 0; i < frameCount; ++i) { println(addresses[i], frames[i]); } @@ -309,36 +312,34 @@ int getFD(const std::ios& stream) { return sbuf->fd(); } } -#endif // __GNUC__ +#endif // __GNUC__ return -1; } bool isColorfulTty(int options, int fd) { if ((options & SymbolizePrinter::TERSE) != 0 || - (options & SymbolizePrinter::COLOR_IF_TTY) == 0 || - fd < 0 || !::isatty(fd)) { + (options & SymbolizePrinter::COLOR_IF_TTY) == 0 || fd < 0 || + !::isatty(fd)) { return false; } auto term = ::getenv("TERM"); return !(term == nullptr || term[0] == '\0' || strcmp(term, "dumb") == 0); } -} // anonymous namespace +} // anonymous namespace OStreamSymbolizePrinter::OStreamSymbolizePrinter(std::ostream& out, int options) - : SymbolizePrinter(options, isColorfulTty(options, getFD(out))), - out_(out) { -} + : SymbolizePrinter(options, isColorfulTty(options, getFD(out))), + out_(out) {} void OStreamSymbolizePrinter::doPrint(StringPiece sp) { out_ << sp; } FDSymbolizePrinter::FDSymbolizePrinter(int fd, int options, size_t bufferSize) - : SymbolizePrinter(options, isColorfulTty(options, fd)), - fd_(fd), - buffer_(bufferSize ? IOBuf::create(bufferSize) : nullptr) { -} + : SymbolizePrinter(options, isColorfulTty(options, fd)), + fd_(fd), + buffer_(bufferSize ? IOBuf::create(bufferSize) : nullptr) {} FDSymbolizePrinter::~FDSymbolizePrinter() { flush(); @@ -366,9 +367,8 @@ void FDSymbolizePrinter::flush() { } FILESymbolizePrinter::FILESymbolizePrinter(FILE* file, int options) - : SymbolizePrinter(options, isColorfulTty(options, fileno(file))), - file_(file) { -} + : SymbolizePrinter(options, isColorfulTty(options, fileno(file))), + file_(file) {} void FILESymbolizePrinter::doPrint(StringPiece sp) { fwrite(sp.data(), 1, sp.size(), file_); @@ -422,5 +422,5 @@ void StackTracePrinter::printStackTrace(bool symbolize) { } } -} // namespace symbolizer -} // namespace folly +} // namespace symbolizer +} // namespace folly diff --git a/folly/experimental/symbolizer/Symbolizer.h b/folly/experimental/symbolizer/Symbolizer.h index 73e7dfdd..1f0dd6da 100644 --- a/folly/experimental/symbolizer/Symbolizer.h +++ b/folly/experimental/symbolizer/Symbolizer.h @@ -39,13 +39,16 @@ class Symbolizer; * Frame information: symbol name and location. */ struct SymbolizedFrame { - SymbolizedFrame() { } + SymbolizedFrame() {} - void set(const std::shared_ptr& file, - uintptr_t address, - Dwarf::LocationInfoMode mode); + void set( + const std::shared_ptr& file, + uintptr_t address, + Dwarf::LocationInfoMode mode); - void clear() { *this = SymbolizedFrame(); } + void clear() { + *this = SymbolizedFrame(); + } bool found = false; const char* name = nullptr; @@ -64,7 +67,7 @@ struct SymbolizedFrame { template struct FrameArray { - FrameArray() { } + FrameArray() {} size_t frameCount = 0; uintptr_t addresses[N]; @@ -90,7 +93,7 @@ bool fixFrameArray(FrameArray& fa, ssize_t n) { return false; } } -} // namespace detail +} // namespace detail // Always inline these functions; they don't do much, and unittests rely // on them never showing up in a stack trace. @@ -115,17 +118,19 @@ class Symbolizer { Dwarf::LocationInfoMode::FAST; explicit Symbolizer(Dwarf::LocationInfoMode mode = kDefaultLocationInfoMode) - : Symbolizer(nullptr, mode) {} + : Symbolizer(nullptr, mode) {} - explicit Symbolizer(ElfCacheBase* cache, - Dwarf::LocationInfoMode mode = kDefaultLocationInfoMode); + explicit Symbolizer( + ElfCacheBase* cache, + Dwarf::LocationInfoMode mode = kDefaultLocationInfoMode); /** * Symbolize given addresses. */ - void symbolize(const uintptr_t* addresses, - SymbolizedFrame* frames, - size_t frameCount); + void symbolize( + const uintptr_t* addresses, + SymbolizedFrame* frames, + size_t frameCount); template void symbolize(FrameArray& fa) { @@ -181,27 +186,30 @@ class SymbolizePrinter { /** * Print multiple addresses on separate lines. */ - void println(const uintptr_t* addresses, - const SymbolizedFrame* frames, - size_t frameCount); + void println( + const uintptr_t* addresses, + const SymbolizedFrame* frames, + size_t frameCount); /** * Print a string, no endling newline. */ - void print(StringPiece sp) { doPrint(sp); } + void print(StringPiece sp) { + doPrint(sp); + } /** * Print multiple addresses on separate lines, skipping the first * skip addresses. */ template - void println(const FrameArray& fa, size_t skip=0) { + void println(const FrameArray& fa, size_t skip = 0) { if (skip < fa.frameCount) { println(fa.addresses + skip, fa.frames + skip, fa.frameCount - skip); } } - virtual ~SymbolizePrinter() { } + virtual ~SymbolizePrinter() {} enum Options { // Skip file and line information @@ -226,9 +234,7 @@ class SymbolizePrinter { protected: explicit SymbolizePrinter(int options, bool isTty = false) - : options_(options), - isTty_(isTty) { - } + : options_(options), isTty_(isTty) {} const int options_; const bool isTty_; @@ -255,7 +261,8 @@ class SymbolizePrinter { */ class OStreamSymbolizePrinter : public SymbolizePrinter { public: - explicit OStreamSymbolizePrinter(std::ostream& out, int options=0); + explicit OStreamSymbolizePrinter(std::ostream& out, int options = 0); + private: void doPrint(StringPiece sp) override; std::ostream& out_; @@ -267,10 +274,10 @@ class OStreamSymbolizePrinter : public SymbolizePrinter { */ class FDSymbolizePrinter : public SymbolizePrinter { public: - explicit FDSymbolizePrinter(int fd, int options=0, - size_t bufferSize=0); + explicit FDSymbolizePrinter(int fd, int options = 0, size_t bufferSize = 0); ~FDSymbolizePrinter() override; void flush(); + private: void doPrint(StringPiece sp) override; @@ -284,7 +291,8 @@ class FDSymbolizePrinter : public SymbolizePrinter { */ class FILESymbolizePrinter : public SymbolizePrinter { public: - explicit FILESymbolizePrinter(FILE* file, int options=0); + explicit FILESymbolizePrinter(FILE* file, int options = 0); + private: void doPrint(StringPiece sp) override; FILE* const file_ = nullptr; @@ -296,11 +304,18 @@ class FILESymbolizePrinter : public SymbolizePrinter { */ class StringSymbolizePrinter : public SymbolizePrinter { public: - explicit StringSymbolizePrinter(int options=0) : SymbolizePrinter(options) { } + explicit StringSymbolizePrinter(int options = 0) + : SymbolizePrinter(options) {} - std::string str() const { return buf_.toStdString(); } - const fbstring& fbstr() const { return buf_; } - fbstring moveFbString() { return std::move(buf_); } + std::string str() const { + return buf_.toStdString(); + } + const fbstring& fbstr() const { + return buf_; + } + fbstring moveFbString() { + return std::move(buf_); + } private: void doPrint(StringPiece sp) override; @@ -352,5 +367,5 @@ class StackTracePrinter { std::unique_ptr> addresses_; }; -} // namespace symbolizer -} // namespace folly +} // namespace symbolizer +} // namespace folly diff --git a/folly/experimental/symbolizer/test/DwarfTests.cpp b/folly/experimental/symbolizer/test/DwarfTests.cpp index 36882d7c..bae2ce00 100644 --- a/folly/experimental/symbolizer/test/DwarfTests.cpp +++ b/folly/experimental/symbolizer/test/DwarfTests.cpp @@ -31,11 +31,11 @@ void checkPath( Dwarf::Path path(rawBaseDir, rawSubDir, rawFile); CHECK_EQ(expectedBaseDir, path.baseDir()) - << "Path(" << rawBaseDir << ", " << rawSubDir << ", " << rawFile << ")"; + << "Path(" << rawBaseDir << ", " << rawSubDir << ", " << rawFile << ")"; CHECK_EQ(expectedSubDir, path.subDir()) - << "Path(" << rawBaseDir << ", " << rawSubDir << ", " << rawFile << ")"; + << "Path(" << rawBaseDir << ", " << rawSubDir << ", " << rawFile << ")"; CHECK_EQ(expectedFile, path.file()) - << "Path(" << rawBaseDir << ", " << rawSubDir << ", " << rawFile << ")"; + << "Path(" << rawBaseDir << ", " << rawSubDir << ", " << rawFile << ")"; CHECK_EQ(expectedPath, path.toString()); @@ -47,52 +47,11 @@ void checkPath( } TEST(Dwarf, Path) { + checkPath("hello.cpp", "", "", "hello.cpp", "", "", "hello.cpp"); + checkPath("foo/hello.cpp", "foo", "", "hello.cpp", "foo", "", "hello.cpp"); + checkPath("foo/hello.cpp", "foo", "", "hello.cpp", "", "foo", "hello.cpp"); + checkPath("hello.cpp", "", "", "hello.cpp", "./////", "./////", "hello.cpp"); + checkPath("/hello.cpp", "/", "", "hello.cpp", "/////", "./////", "hello.cpp"); checkPath( - "hello.cpp", - "", - "", - "hello.cpp", - "", - "", - "hello.cpp"); - checkPath( - "foo/hello.cpp", - "foo", - "", - "hello.cpp", - "foo", - "", - "hello.cpp"); - checkPath( - "foo/hello.cpp", - "foo", - "", - "hello.cpp", - "", - "foo", - "hello.cpp"); - checkPath( - "hello.cpp", - "", - "", - "hello.cpp", - "./////", - "./////", - "hello.cpp"); - checkPath( - "/hello.cpp", - "/", - "", - "hello.cpp", - "/////", - "./////", - "hello.cpp"); - checkPath( - "/hello.cpp", - "/", - "", - "hello.cpp", - "/./././././././", - "", - "hello.cpp"); + "/hello.cpp", "/", "", "hello.cpp", "/./././././././", "", "hello.cpp"); } diff --git a/folly/experimental/symbolizer/test/ElfTests.cpp b/folly/experimental/symbolizer/test/ElfTests.cpp index 03f6df53..f27fef41 100644 --- a/folly/experimental/symbolizer/test/ElfTests.cpp +++ b/folly/experimental/symbolizer/test/ElfTests.cpp @@ -29,8 +29,7 @@ class ElfTest : public ::testing::Test { // Path to the test binary itself; set by main() static std::string binaryPath; - ElfTest() : elfFile_(binaryPath.c_str()) { - } + ElfTest() : elfFile_(binaryPath.c_str()) {} ~ElfTest() override {} protected: @@ -41,17 +40,15 @@ std::string ElfTest::binaryPath; TEST_F(ElfTest, IntegerValue) { auto sym = elfFile_.getSymbolByName("kIntegerValue"); - EXPECT_NE(nullptr, sym.first) << - "Failed to look up symbol kIntegerValue"; + EXPECT_NE(nullptr, sym.first) << "Failed to look up symbol kIntegerValue"; EXPECT_EQ(kIntegerValue, elfFile_.getSymbolValue(sym.second)); } TEST_F(ElfTest, PointerValue) { auto sym = elfFile_.getSymbolByName("kStringValue"); - EXPECT_NE(nullptr, sym.first) << - "Failed to look up symbol kStringValue"; + EXPECT_NE(nullptr, sym.first) << "Failed to look up symbol kStringValue"; ElfW(Addr) addr = elfFile_.getSymbolValue(sym.second); - const char *str = &elfFile_.getAddressValue(addr); + const char* str = &elfFile_.getAddressValue(addr); EXPECT_STREQ(kStringValue, str); } diff --git a/folly/experimental/symbolizer/test/LineReaderTest.cpp b/folly/experimental/symbolizer/test/LineReaderTest.cpp index 2746a336..9df86cf3 100644 --- a/folly/experimental/symbolizer/test/LineReaderTest.cpp +++ b/folly/experimental/symbolizer/test/LineReaderTest.cpp @@ -22,7 +22,9 @@ #include #include -namespace folly { namespace symbolizer { namespace test { +namespace folly { +namespace symbolizer { +namespace test { using folly::test::TemporaryFile; @@ -34,8 +36,9 @@ void writeAll(int fd, const char* str) { void expect(LineReader& lr, const char* expected) { StringPiece line; size_t expectedLen = strlen(expected); - EXPECT_EQ(expectedLen != 0 ? LineReader::kReading : LineReader::kEof, - lr.readLine(line)); + EXPECT_EQ( + expectedLen != 0 ? LineReader::kReading : LineReader::kEof, + lr.readLine(line)); EXPECT_EQ(expectedLen, line.size()); EXPECT_EQ(std::string(expected, expectedLen), line.str()); } @@ -43,12 +46,13 @@ void expect(LineReader& lr, const char* expected) { TEST(LineReader, Simple) { TemporaryFile file; int fd = file.fd(); - writeAll(fd, - "Meow\n" - "Hello world\n" - "This is a long line. It is longer than the other lines.\n" - "\n" - "Incomplete last line"); + writeAll( + fd, + "Meow\n" + "Hello world\n" + "This is a long line. It is longer than the other lines.\n" + "\n" + "Incomplete last line"); { CHECK_ERR(lseek(fd, 0, SEEK_SET)); @@ -81,5 +85,6 @@ TEST(LineReader, Simple) { expect(lr, ""); } } - -}}} // namespaces +} // namespace test +} // namespace symbolizer +} // namespace folly diff --git a/folly/experimental/symbolizer/test/SignalHandlerTest.cpp b/folly/experimental/symbolizer/test/SignalHandlerTest.cpp index 56c216fd..899f3809 100644 --- a/folly/experimental/symbolizer/test/SignalHandlerTest.cpp +++ b/folly/experimental/symbolizer/test/SignalHandlerTest.cpp @@ -22,7 +22,9 @@ #include #include -namespace folly { namespace symbolizer { namespace test { +namespace folly { +namespace symbolizer { +namespace test { namespace { @@ -30,7 +32,6 @@ void print(StringPiece sp) { writeFull(STDERR_FILENO, sp.data(), sp.size()); } - void callback1() { print("Callback1\n"); } @@ -39,7 +40,7 @@ void callback2() { print("Callback2\n"); } -} // namespace +} // namespace TEST(SignalHandler, Simple) { addFatalSignalCallback(callback1); @@ -73,9 +74,9 @@ TEST(SignalHandler, Simple) { "Callback2\n"); #endif } - - -}}} // namespaces +} // namespace test +} // namespace symbolizer +} // namespace folly // Can't use initFacebookLight since that would install its own signal handlers // Can't use initFacebookNoSignals since we cannot depend on common diff --git a/folly/experimental/symbolizer/test/SignalHandlerTest.h b/folly/experimental/symbolizer/test/SignalHandlerTest.h index e53cc7d0..e9e769b9 100644 --- a/folly/experimental/symbolizer/test/SignalHandlerTest.h +++ b/folly/experimental/symbolizer/test/SignalHandlerTest.h @@ -16,10 +16,13 @@ #pragma once -namespace folly { namespace symbolizer { namespace test { +namespace folly { +namespace symbolizer { +namespace test { inline void failHard() { - *(/* nolint */ volatile char*)42; // SIGSEGV + *(/* nolint */ volatile char*)42; // SIGSEGV } - -}}} // namespaces +} // namespace test +} // namespace symbolizer +} // namespace folly diff --git a/folly/experimental/symbolizer/test/StackTraceTest.cpp b/folly/experimental/symbolizer/test/StackTraceTest.cpp index a1a7c99e..99e8c322 100644 --- a/folly/experimental/symbolizer/test/StackTraceTest.cpp +++ b/folly/experimental/symbolizer/test/StackTraceTest.cpp @@ -89,7 +89,7 @@ TEST(StackTraceTest, Signal) { EXPECT_TRUE(handled); } -int main(int argc, char *argv[]) { +int main(int argc, char* argv[]) { testing::InitGoogleTest(&argc, argv); gflags::ParseCommandLineFlags(&argc, &argv, true); google::InitGoogleLogging(argv[0]); diff --git a/folly/experimental/symbolizer/test/SymbolizerTest.cpp b/folly/experimental/symbolizer/test/SymbolizerTest.cpp index e23b925d..e0ba5e42 100644 --- a/folly/experimental/symbolizer/test/SymbolizerTest.cpp +++ b/folly/experimental/symbolizer/test/SymbolizerTest.cpp @@ -22,10 +22,11 @@ #include #include -namespace folly { namespace symbolizer { namespace test { +namespace folly { +namespace symbolizer { +namespace test { -void foo() { -} +void foo() {} TEST(Symbolizer, Single) { Symbolizer symbolizer; @@ -36,11 +37,11 @@ TEST(Symbolizer, Single) { // The version of clang we use doesn't generate a `.debug_aranges` section, // which the symbolizer needs to lookup the filename. constexpr bool built_with_clang = - #ifdef __clang__ +#ifdef __clang__ true; - #else +#else false; - #endif +#endif if (!built_with_clang) { auto path = a.location.file.toString(); folly::StringPiece basename(path); @@ -113,8 +114,9 @@ TEST_F(ElfCacheTest, SignalSafeElfCache) { runElfCacheTest(symbolizer); } } - -}}} // namespaces +} // namespace test +} // namespace symbolizer +} // namespace folly // Can't use initFacebookLight since that would install its own signal handlers // Can't use initFacebookNoSignals since we cannot depend on common -- 2.34.1