Commit 04458d15 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

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
parent f7920221
This diff is collapsed.
...@@ -63,14 +63,22 @@ class Dwarf { ...@@ -63,14 +63,22 @@ class Dwarf {
*/ */
class Path { class Path {
public: public:
Path() { } Path() {}
Path(folly::StringPiece baseDir, folly::StringPiece subDir, Path(
folly::StringPiece baseDir,
folly::StringPiece subDir,
folly::StringPiece file); folly::StringPiece file);
folly::StringPiece baseDir() const { return baseDir_; } folly::StringPiece baseDir() const {
folly::StringPiece subDir() const { return subDir_; } return baseDir_;
folly::StringPiece file() const { return file_; } }
folly::StringPiece subDir() const {
return subDir_;
}
folly::StringPiece file() const {
return file_;
}
size_t size() const; size_t size() const;
...@@ -121,17 +129,16 @@ class Dwarf { ...@@ -121,17 +129,16 @@ class Dwarf {
/** /**
* Find the file and line number information corresponding to address. * Find the file and line number information corresponding to address.
*/ */
bool findAddress(uintptr_t address, bool findAddress(uintptr_t address, LocationInfo& info, LocationInfoMode mode)
LocationInfo& info, const;
LocationInfoMode mode) const;
private: private:
static bool findDebugInfoOffset(uintptr_t address, static bool
StringPiece aranges, findDebugInfoOffset(uintptr_t address, StringPiece aranges, uint64_t& offset);
uint64_t& offset);
void init(); void init();
bool findLocation(uintptr_t address, bool findLocation(
uintptr_t address,
StringPiece& infoEntry, StringPiece& infoEntry,
LocationInfo& info) const; LocationInfo& info) const;
...@@ -143,7 +150,7 @@ class Dwarf { ...@@ -143,7 +150,7 @@ class Dwarf {
// (yes, DWARF-32 and DWARF-64 sections may coexist in the same file) // (yes, DWARF-32 and DWARF-64 sections may coexist in the same file)
class Section { class Section {
public: public:
Section() : is64Bit_(false) { } Section() : is64Bit_(false) {}
explicit Section(folly::StringPiece d); explicit Section(folly::StringPiece d);
...@@ -152,7 +159,9 @@ class Dwarf { ...@@ -152,7 +159,9 @@ class Dwarf {
bool next(folly::StringPiece& chunk); bool next(folly::StringPiece& chunk);
// Is the current chunk 64 bit? // Is the current chunk 64 bit?
bool is64Bit() const { return is64Bit_; } bool is64Bit() const {
return is64Bit_;
}
private: private:
// Yes, 32- and 64- bit sections may coexist. Yikes! // Yes, 32- and 64- bit sections may coexist. Yikes!
...@@ -177,7 +186,8 @@ class Dwarf { ...@@ -177,7 +186,8 @@ class Dwarf {
// Interpreter for the line number bytecode VM // Interpreter for the line number bytecode VM
class LineNumberVM { class LineNumberVM {
public: public:
LineNumberVM(folly::StringPiece data, LineNumberVM(
folly::StringPiece data,
folly::StringPiece compilationDirectory); folly::StringPiece compilationDirectory);
bool findAddress(uintptr_t address, Path& file, uint64_t& line); bool findAddress(uintptr_t address, Path& file, uint64_t& line);
...@@ -263,10 +273,8 @@ class Dwarf { ...@@ -263,10 +273,8 @@ class Dwarf {
// Read one attribute value, advance sp // Read one attribute value, advance sp
typedef boost::variant<uint64_t, folly::StringPiece> AttributeValue; typedef boost::variant<uint64_t, folly::StringPiece> AttributeValue;
AttributeValue readAttributeValue( AttributeValue
folly::StringPiece& sp, readAttributeValue(folly::StringPiece& sp, uint64_t form, bool is64Bit) const;
uint64_t form,
bool is64Bit) const;
// Get an ELF section by name, return true if found // Get an ELF section by name, return true if found
bool getSection(const char* name, folly::StringPiece* section) const; bool getSection(const char* name, folly::StringPiece* section) const;
......
...@@ -14,17 +14,16 @@ ...@@ -14,17 +14,16 @@
* limitations under the License. * limitations under the License.
*/ */
#ifndef FOLLY_EXPERIMENTAL_SYMBOLIZER_ELF_H_ #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 #endif
namespace folly { namespace folly {
namespace symbolizer { namespace symbolizer {
template <class Fn> template <class Fn>
const ElfW(Shdr)* ElfFile::iterateSections(Fn fn) const { const ElfShdr* ElfFile::iterateSections(Fn fn) const {
const ElfW(Shdr)* ptr = &at<ElfW(Shdr)>(elfHeader().e_shoff); const ElfShdr* ptr = &at<ElfShdr>(elfHeader().e_shoff);
for (size_t i = 0; i < elfHeader().e_shnum; i++, ptr++) { for (size_t i = 0; i < elfHeader().e_shnum; i++, ptr++) {
if (fn(*ptr)) { if (fn(*ptr)) {
return ptr; return ptr;
...@@ -35,17 +34,13 @@ const ElfW(Shdr)* ElfFile::iterateSections(Fn fn) const { ...@@ -35,17 +34,13 @@ const ElfW(Shdr)* ElfFile::iterateSections(Fn fn) const {
} }
template <class Fn> template <class Fn>
const ElfW(Shdr)* ElfFile::iterateSectionsWithType(uint32_t type, Fn fn) const ElfShdr* ElfFile::iterateSectionsWithType(uint32_t type, Fn fn) const {
const {
return iterateSections( return iterateSections(
[&](const ElfW(Shdr)& sh) { [&](const ElfShdr& sh) { return sh.sh_type == type && fn(sh); });
return sh.sh_type == type && fn(sh);
});
} }
template <class Fn> template <class Fn>
const char* ElfFile::iterateStrings(const ElfW(Shdr)& stringTable, Fn fn) const char* ElfFile::iterateStrings(const ElfShdr& stringTable, Fn fn) const {
const {
validateStringTable(stringTable); validateStringTable(stringTable);
const char* start = file_ + stringTable.sh_offset; const char* start = file_ + stringTable.sh_offset;
...@@ -60,13 +55,13 @@ const char* ElfFile::iterateStrings(const ElfW(Shdr)& stringTable, Fn fn) ...@@ -60,13 +55,13 @@ const char* ElfFile::iterateStrings(const ElfW(Shdr)& stringTable, Fn fn)
} }
template <class Fn> template <class Fn>
const ElfW(Sym)* ElfFile::iterateSymbols(const ElfW(Shdr)& section, Fn fn) const ElfSym* ElfFile::iterateSymbols(const ElfShdr& section, Fn fn) const {
const { FOLLY_SAFE_CHECK(
FOLLY_SAFE_CHECK(section.sh_entsize == sizeof(ElfW(Sym)), section.sh_entsize == sizeof(ElfSym),
"invalid entry size in symbol table"); "invalid entry size in symbol table");
const ElfW(Sym)* sym = &at<ElfW(Sym)>(section.sh_offset); const ElfSym* sym = &at<ElfSym>(section.sh_offset);
const ElfW(Sym)* end = sym + (section.sh_size / section.sh_entsize); const ElfSym* end = sym + (section.sh_size / section.sh_entsize);
while (sym < end) { while (sym < end) {
if (fn(*sym)) { if (fn(*sym)) {
...@@ -80,10 +75,12 @@ const ElfW(Sym)* ElfFile::iterateSymbols(const ElfW(Shdr)& section, Fn fn) ...@@ -80,10 +75,12 @@ const ElfW(Sym)* ElfFile::iterateSymbols(const ElfW(Shdr)& section, Fn fn)
} }
template <class Fn> template <class Fn>
const ElfW(Sym)* ElfFile::iterateSymbolsWithType(const ElfW(Shdr)& section, const ElfSym* ElfFile::iterateSymbolsWithType(
uint32_t type, Fn fn) const { const ElfShdr& section,
uint32_t type,
Fn fn) const {
// N.B. st_info has the same representation on 32- and 64-bit platforms // 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); return ELF32_ST_TYPE(sym.st_info) == type && fn(sym);
}); });
} }
......
This diff is collapsed.
...@@ -34,6 +34,13 @@ ...@@ -34,6 +34,13 @@
namespace folly { namespace folly {
namespace symbolizer { 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. * ELF file parser.
* *
...@@ -46,7 +53,7 @@ class ElfFile { ...@@ -46,7 +53,7 @@ class ElfFile {
ElfFile() noexcept; ElfFile() noexcept;
// Note: may throw, call openNoThrow() explicitly if you don't want to throw // 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. // Open the ELF file.
// Returns 0 on success, kSystemError (guaranteed to be -1) (and sets errno) // Returns 0 on success, kSystemError (guaranteed to be -1) (and sets errno)
...@@ -59,15 +66,19 @@ class ElfFile { ...@@ -59,15 +66,19 @@ class ElfFile {
kInvalidElfFile = -2, kInvalidElfFile = -2,
}; };
// Open the ELF file. Does not throw on error. // Open the ELF file. Does not throw on error.
int openNoThrow(const char* name, bool readOnly=true, int openNoThrow(
const char** msg=nullptr) noexcept; const char* name,
bool readOnly = true,
const char** msg = nullptr) noexcept;
// Like openNoThrow, but follow .gnu_debuglink if present // Like openNoThrow, but follow .gnu_debuglink if present
int openAndFollow(const char* name, bool readOnly=true, int openAndFollow(
const char** msg=nullptr) noexcept; const char* name,
bool readOnly = true,
const char** msg = nullptr) noexcept;
// Open the ELF file. Throws on error. // Open the ELF file. Throws on error.
void open(const char* name, bool readOnly=true); void open(const char* name, bool readOnly = true);
~ElfFile(); ~ElfFile();
...@@ -75,8 +86,8 @@ class ElfFile { ...@@ -75,8 +86,8 @@ class ElfFile {
ElfFile& operator=(ElfFile&& other); ElfFile& operator=(ElfFile&& other);
/** Retrieve the ELF header */ /** Retrieve the ELF header */
const ElfW(Ehdr)& elfHeader() const { const ElfEhdr& elfHeader() const {
return at<ElfW(Ehdr)>(0); return at<ElfEhdr>(0);
} }
/** /**
...@@ -88,19 +99,19 @@ class ElfFile { ...@@ -88,19 +99,19 @@ class ElfFile {
} }
/** Find a section given its name */ /** 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 */ /** 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 */ /** 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 */ /** 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 */ /** 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 * Iterate over all strings in a string table section for as long as
...@@ -109,7 +120,7 @@ class ElfFile { ...@@ -109,7 +120,7 @@ class ElfFile {
* if fn returned false for all strings in the table. * if fn returned false for all strings in the table.
*/ */
template <class Fn> template <class Fn>
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. * Iterate over all sections for as long as fn(section) returns false.
...@@ -117,14 +128,14 @@ class ElfFile { ...@@ -117,14 +128,14 @@ class ElfFile {
* true, or nullptr if fn returned false for all sections. * true, or nullptr if fn returned false for all sections.
*/ */
template <class Fn> template <class Fn>
const ElfW(Shdr)* iterateSections(Fn fn) const; const ElfShdr* iterateSections(Fn fn) const;
/** /**
* Iterate over all sections with a given type. Similar to * Iterate over all sections with a given type. Similar to
* iterateSections(), but filtered only for sections with the given type. * iterateSections(), but filtered only for sections with the given type.
*/ */
template <class Fn> template <class Fn>
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. * Iterate over all symbols witin a given section.
...@@ -133,10 +144,10 @@ class ElfFile { ...@@ -133,10 +144,10 @@ class ElfFile {
* or nullptr if fn returned false for all symbols. * or nullptr if fn returned false for all symbols.
*/ */
template <class Fn> template <class Fn>
const ElfW(Sym)* iterateSymbols(const ElfW(Shdr)& section, Fn fn) const; const ElfSym* iterateSymbols(const ElfShdr& section, Fn fn) const;
template <class Fn> template <class Fn>
const ElfW(Sym)* iterateSymbolsWithType(const ElfW(Shdr)& section, const ElfSym*
uint32_t type, Fn fn) const; iterateSymbolsWithType(const ElfShdr& section, uint32_t type, Fn fn) const;
/** /**
* Find symbol definition by address. * Find symbol definition by address.
...@@ -145,7 +156,7 @@ class ElfFile { ...@@ -145,7 +156,7 @@ class ElfFile {
* *
* Returns {nullptr, nullptr} if not found. * Returns {nullptr, nullptr} if not found.
*/ */
typedef std::pair<const ElfW(Shdr)*, const ElfW(Sym)*> Symbol; typedef std::pair<const ElfShdr*, const ElfSym*> Symbol;
Symbol getDefinitionByAddress(uintptr_t address) const; Symbol getDefinitionByAddress(uintptr_t address) const;
/** /**
...@@ -162,8 +173,8 @@ class ElfFile { ...@@ -162,8 +173,8 @@ class ElfFile {
* Get the value of a symbol. * Get the value of a symbol.
*/ */
template <class T> template <class T>
const T& getSymbolValue(const ElfW(Sym)* symbol) const { const T& getSymbolValue(const ElfSym* symbol) const {
const ElfW(Shdr)* section = getSectionByIndex(symbol->st_shndx); const ElfShdr* section = getSectionByIndex(symbol->st_shndx);
FOLLY_SAFE_CHECK(section, "Symbol's section index is invalid"); FOLLY_SAFE_CHECK(section, "Symbol's section index is invalid");
return valueAt<T>(*section, symbol->st_value); return valueAt<T>(*section, symbol->st_value);
...@@ -177,12 +188,12 @@ class ElfFile { ...@@ -177,12 +188,12 @@ class ElfFile {
* a char* symbol, you'd do something like this: * a char* symbol, you'd do something like this:
* *
* auto sym = getSymbolByName("someGlobalValue"); * auto sym = getSymbolByName("someGlobalValue");
* auto addr = getSymbolValue<ElfW(Addr)>(sym.second); * auto addr = getSymbolValue<ElfAddr>(sym.second);
* const char* str = &getSymbolValue<const char>(addr); * const char* str = &getSymbolValue<const char>(addr);
*/ */
template <class T> template <class T>
const T& getAddressValue(const ElfW(Addr) addr) const { const T& getAddressValue(const ElfAddr addr) const {
const ElfW(Shdr)* section = getSectionContainingAddress(addr); const ElfShdr* section = getSectionContainingAddress(addr);
FOLLY_SAFE_CHECK(section, "Address does not refer to existing section"); FOLLY_SAFE_CHECK(section, "Address does not refer to existing section");
return valueAt<T>(*section, addr); return valueAt<T>(*section, addr);
...@@ -194,7 +205,7 @@ class ElfFile { ...@@ -194,7 +205,7 @@ class ElfFile {
const char* getSymbolName(Symbol symbol) const; const char* getSymbolName(Symbol symbol) const;
/** Find the section containing the given address */ /** Find the section containing the given address */
const ElfW(Shdr)* getSectionContainingAddress(ElfW(Addr) addr) const; const ElfShdr* getSectionContainingAddress(ElfAddr addr) const;
private: private:
bool init(const char** msg); bool init(const char** msg);
...@@ -202,19 +213,20 @@ class ElfFile { ...@@ -202,19 +213,20 @@ class ElfFile {
ElfFile(const ElfFile&) = delete; ElfFile(const ElfFile&) = delete;
ElfFile& operator=(const ElfFile&) = delete; ElfFile& operator=(const ElfFile&) = delete;
void validateStringTable(const ElfW(Shdr)& stringTable) const; void validateStringTable(const ElfShdr& stringTable) const;
template <class T> template <class T>
const typename std::enable_if<std::is_pod<T>::value, T>::type& const typename std::enable_if<std::is_pod<T>::value, T>::type& at(
at(ElfW(Off) offset) const { ElfOff offset) const {
FOLLY_SAFE_CHECK(offset + sizeof(T) <= length_, FOLLY_SAFE_CHECK(
offset + sizeof(T) <= length_,
"Offset is not contained within our mmapped file"); "Offset is not contained within our mmapped file");
return *reinterpret_cast<T*>(file_ + offset); return *reinterpret_cast<T*>(file_ + offset);
} }
template <class T> template <class T>
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 // 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 // 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 // sections into the addresses that they're expecting (sh_addr), but
......
...@@ -26,7 +26,8 @@ ...@@ -26,7 +26,8 @@
*/ */
extern struct r_debug _r_debug; extern struct r_debug _r_debug;
namespace folly { namespace symbolizer { namespace folly {
namespace symbolizer {
size_t countLoadedElfFiles() { size_t countLoadedElfFiles() {
// _r_debug synchronization is... lacking to say the least. It's // _r_debug synchronization is... lacking to say the least. It's
...@@ -88,7 +89,7 @@ std::shared_ptr<ElfFile> SignalSafeElfCache::getFile(StringPiece p) { ...@@ -88,7 +89,7 @@ std::shared_ptr<ElfFile> SignalSafeElfCache::getFile(StringPiece p) {
return f; return f;
} }
ElfCache::ElfCache(size_t capacity) : capacity_(capacity) { } ElfCache::ElfCache(size_t capacity) : capacity_(capacity) {}
std::shared_ptr<ElfFile> ElfCache::getFile(StringPiece p) { std::shared_ptr<ElfFile> ElfCache::getFile(StringPiece p) {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
...@@ -129,5 +130,5 @@ std::shared_ptr<ElfFile> ElfCache::filePtr(const std::shared_ptr<Entry>& e) { ...@@ -129,5 +130,5 @@ std::shared_ptr<ElfFile> ElfCache::filePtr(const std::shared_ptr<Entry>& e) {
// share ownership // share ownership
return std::shared_ptr<ElfFile>(e, &e->file); return std::shared_ptr<ElfFile>(e, &e->file);
} }
} // namespace symbolizer
}} // namespaces } // namespace folly
...@@ -33,7 +33,8 @@ ...@@ -33,7 +33,8 @@
#include <folly/Range.h> #include <folly/Range.h>
#include <folly/experimental/symbolizer/Elf.h> #include <folly/experimental/symbolizer/Elf.h>
namespace folly { namespace symbolizer { namespace folly {
namespace symbolizer {
/** /**
* Number of ELF files loaded by the dynamic loader. * Number of ELF files loaded by the dynamic loader.
...@@ -43,7 +44,7 @@ size_t countLoadedElfFiles(); ...@@ -43,7 +44,7 @@ size_t countLoadedElfFiles();
class ElfCacheBase { class ElfCacheBase {
public: public:
virtual std::shared_ptr<ElfFile> getFile(StringPiece path) = 0; virtual std::shared_ptr<ElfFile> getFile(StringPiece path) = 0;
virtual ~ElfCacheBase() { } virtual ~ElfCacheBase() {}
}; };
/** /**
...@@ -139,8 +140,9 @@ class ElfCache : public ElfCacheBase { ...@@ -139,8 +140,9 @@ class ElfCache : public ElfCacheBase {
typedef boost::intrusive::list< typedef boost::intrusive::list<
Entry, Entry,
boost::intrusive::member_hook<Entry, LruLink, &Entry::lruLink>, boost::intrusive::member_hook<Entry, LruLink, &Entry::lruLink>,
boost::intrusive::constant_time_size<false>> LruList; boost::intrusive::constant_time_size<false>>
LruList;
LruList lruList_; LruList lruList_;
}; };
} // namespace symbolizer
}} // namespaces } // namespace folly
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
* limitations under the License. * limitations under the License.
*/ */
#include <folly/experimental/symbolizer/Elf.h> #include <folly/experimental/symbolizer/Elf.h>
#include <stdio.h> #include <stdio.h>
...@@ -26,7 +25,7 @@ ...@@ -26,7 +25,7 @@
using namespace folly; using namespace folly;
using namespace folly::symbolizer; using namespace folly::symbolizer;
int main(int argc, char *argv[]) { int main(int argc, char* argv[]) {
gflags::ParseCommandLineFlags(&argc, &argv, true); gflags::ParseCommandLineFlags(&argc, &argv, true);
CHECK_GE(argc, 2); CHECK_GE(argc, 2);
...@@ -34,9 +33,7 @@ int main(int argc, char *argv[]) { ...@@ -34,9 +33,7 @@ int main(int argc, char *argv[]) {
if (argc > 2) { if (argc > 2) {
auto section = elf.getSectionByName(argv[2]); auto section = elf.getSectionByName(argv[2]);
printf("Section %s: %s\n", printf("Section %s: %s\n", argv[2], (section ? "found" : "not found"));
argv[2],
(section ? "found" : "not found"));
} }
auto sym = elf.getDefinitionByAddress(reinterpret_cast<uintptr_t>(main)); auto sym = elf.getDefinitionByAddress(reinterpret_cast<uintptr_t>(main));
......
...@@ -20,7 +20,8 @@ ...@@ -20,7 +20,8 @@
#include <folly/FileUtil.h> #include <folly/FileUtil.h>
namespace folly { namespace symbolizer { namespace folly {
namespace symbolizer {
LineReader::LineReader(int fd, char* buf, size_t bufSize) LineReader::LineReader(int fd, char* buf, size_t bufSize)
: fd_(fd), : fd_(fd),
...@@ -29,8 +30,7 @@ LineReader::LineReader(int fd, char* buf, size_t bufSize) ...@@ -29,8 +30,7 @@ LineReader::LineReader(int fd, char* buf, size_t bufSize)
bol_(buf), bol_(buf),
eol_(buf), eol_(buf),
end_(buf), end_(buf),
state_(kReading) { state_(kReading) {}
}
LineReader::State LineReader::readLine(StringPiece& line) { LineReader::State LineReader::readLine(StringPiece& line) {
bol_ = eol_; // Start past what we already returned bol_ = eol_; // Start past what we already returned
...@@ -69,5 +69,5 @@ LineReader::State LineReader::readLine(StringPiece& line) { ...@@ -69,5 +69,5 @@ LineReader::State LineReader::readLine(StringPiece& line) {
line.assign(bol_, eol_); line.assign(bol_, eol_);
return eol_ != bol_ ? kReading : state_; return eol_ != bol_ ? kReading : state_;
} }
} // namespace symbolizer
}} // namespaces } // namespace folly
...@@ -22,7 +22,8 @@ ...@@ -22,7 +22,8 @@
#include <folly/Range.h> #include <folly/Range.h>
namespace folly { namespace symbolizer { namespace folly {
namespace symbolizer {
/** /**
* Async-signal-safe line reader. * Async-signal-safe line reader.
...@@ -38,7 +39,7 @@ class LineReader : private boost::noncopyable { ...@@ -38,7 +39,7 @@ class LineReader : private boost::noncopyable {
enum State { enum State {
kReading, kReading,
kEof, kEof,
kError kError,
}; };
/** /**
* Read the next line from the file. * Read the next line from the file.
...@@ -83,5 +84,5 @@ class LineReader : private boost::noncopyable { ...@@ -83,5 +84,5 @@ class LineReader : private boost::noncopyable {
char* end_; char* end_;
State state_; State state_;
}; };
} // namespace symbolizer
}} // namespaces } // namespace folly
...@@ -37,7 +37,8 @@ ...@@ -37,7 +37,8 @@
#include <folly/portability/SysSyscall.h> #include <folly/portability/SysSyscall.h>
#include <folly/portability/Unistd.h> #include <folly/portability/Unistd.h>
namespace folly { namespace symbolizer { namespace folly {
namespace symbolizer {
namespace { namespace {
...@@ -59,13 +60,11 @@ class FatalSignalCallbackRegistry { ...@@ -59,13 +60,11 @@ class FatalSignalCallbackRegistry {
}; };
FatalSignalCallbackRegistry::FatalSignalCallbackRegistry() FatalSignalCallbackRegistry::FatalSignalCallbackRegistry()
: installed_(false) { : installed_(false) {}
}
void FatalSignalCallbackRegistry::add(SignalCallback func) { void FatalSignalCallbackRegistry::add(SignalCallback func) {
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
CHECK(!installed_) CHECK(!installed_) << "FatalSignalCallbackRegistry::add may not be used "
<< "FatalSignalCallbackRegistry::add may not be used "
"after installing the signal handlers."; "after installing the signal handlers.";
handlers_.push_back(func); handlers_.push_back(func);
} }
...@@ -96,13 +95,13 @@ struct { ...@@ -96,13 +95,13 @@ struct {
const char* name; const char* name;
struct sigaction oldAction; struct sigaction oldAction;
} kFatalSignals[] = { } kFatalSignals[] = {
{ SIGSEGV, "SIGSEGV", {} }, {SIGSEGV, "SIGSEGV", {}},
{ SIGILL, "SIGILL", {} }, {SIGILL, "SIGILL", {}},
{ SIGFPE, "SIGFPE", {} }, {SIGFPE, "SIGFPE", {}},
{ SIGABRT, "SIGABRT", {} }, {SIGABRT, "SIGABRT", {}},
{ SIGBUS, "SIGBUS", {} }, {SIGBUS, "SIGBUS", {}},
{ SIGTERM, "SIGTERM", {} }, {SIGTERM, "SIGTERM", {}},
{ 0, nullptr, {} } {0, nullptr, {}},
}; };
void callPreviousSignalHandler(int signum) { void callPreviousSignalHandler(int signum) {
...@@ -163,7 +162,9 @@ void flush() { ...@@ -163,7 +162,9 @@ void flush() {
} }
void dumpTimeInfo() { void dumpTimeInfo() {
SCOPE_EXIT { flush(); }; SCOPE_EXIT {
flush();
};
time_t now = time(nullptr); time_t now = time(nullptr);
print("*** Aborted at "); print("*** Aborted at ");
printDec(now); printDec(now);
...@@ -325,7 +326,9 @@ const char* signal_reason(int signum, int si_code) { ...@@ -325,7 +326,9 @@ const char* signal_reason(int signum, int si_code) {
} }
void dumpSignalInfo(int signum, siginfo_t* siginfo) { void dumpSignalInfo(int signum, siginfo_t* siginfo) {
SCOPE_EXIT { flush(); }; SCOPE_EXIT {
flush();
};
// Get the signal name, if possible. // Get the signal name, if possible.
const char* name = nullptr; const char* name = nullptr;
for (auto p = kFatalSignals; p->name; ++p) { for (auto p = kFatalSignals; p->name; ++p) {
...@@ -415,7 +418,9 @@ void innerSignalHandler(int signum, siginfo_t* info, void* /* uctx */) { ...@@ -415,7 +418,9 @@ void innerSignalHandler(int signum, siginfo_t* info, void* /* uctx */) {
} }
void signalHandler(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); innerSignalHandler(signum, info, uctx);
gSignalThread = kInvalidThreadId; gSignalThread = kInvalidThreadId;
...@@ -460,5 +465,5 @@ void installFatalSignalHandler() { ...@@ -460,5 +465,5 @@ void installFatalSignalHandler() {
CHECK_ERR(sigaction(p->number, &sa, &p->oldAction)); CHECK_ERR(sigaction(p->number, &sa, &p->oldAction));
} }
} }
} // namespace symbolizer
}} // namespaces } // namespace folly
...@@ -18,7 +18,8 @@ ...@@ -18,7 +18,8 @@
#include <functional> #include <functional>
namespace folly { namespace symbolizer { namespace folly {
namespace symbolizer {
/** /**
* Install handler for fatal signals. The list of signals being handled is in * Install handler for fatal signals. The list of signals being handled is in
...@@ -47,5 +48,5 @@ void addFatalSignalCallback(SignalCallback callback); ...@@ -47,5 +48,5 @@ void addFatalSignalCallback(SignalCallback callback);
* callbacks in the order in which they were added. * callbacks in the order in which they were added.
*/ */
void installFatalSignalCallbacks(); void installFatalSignalCallbacks();
} // namespace symbolizer
}} // namespaces } // namespace folly
...@@ -20,11 +20,12 @@ ...@@ -20,11 +20,12 @@
#define UNW_LOCAL_ONLY 1 #define UNW_LOCAL_ONLY 1
#include <libunwind.h> #include <libunwind.h>
namespace folly { namespace symbolizer { namespace folly {
namespace symbolizer {
ssize_t getStackTrace(uintptr_t* addresses, size_t maxAddresses) { ssize_t getStackTrace(uintptr_t* addresses, size_t maxAddresses) {
static_assert(sizeof(uintptr_t) == sizeof(void*), static_assert(
"uinptr_t / pointer size mismatch"); sizeof(uintptr_t) == sizeof(void*), "uinptr_t / pointer size mismatch");
// The libunwind documentation says that unw_backtrace is async-signal-safe // 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 // but, as of libunwind 1.0.1, it isn't (tdep_trace allocates memory on
// x86_64) // x86_64)
...@@ -81,5 +82,5 @@ ssize_t getStackTraceSafe(uintptr_t* addresses, size_t maxAddresses) { ...@@ -81,5 +82,5 @@ ssize_t getStackTraceSafe(uintptr_t* addresses, size_t maxAddresses) {
} }
return count; return count;
} }
} // namespace symbolizer
}} // namespaces } // namespace folly
...@@ -19,7 +19,8 @@ ...@@ -19,7 +19,8 @@
#include <cstdint> #include <cstdint>
#include <cstdlib> #include <cstdlib>
namespace folly { namespace symbolizer { namespace folly {
namespace symbolizer {
/** /**
* Get the current stack trace into addresses, which has room for at least * 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); ...@@ -42,5 +43,5 @@ ssize_t getStackTrace(uintptr_t* addresses, size_t maxAddresses);
* Async-signal-safe, but likely slower. * Async-signal-safe, but likely slower.
*/ */
ssize_t getStackTraceSafe(uintptr_t* addresses, size_t maxAddresses); ssize_t getStackTraceSafe(uintptr_t* addresses, size_t maxAddresses);
} // namespace symbolizer
}} // namespaces } // namespace folly
...@@ -60,7 +60,8 @@ ElfCache* defaultElfCache() { ...@@ -60,7 +60,8 @@ ElfCache* defaultElfCache() {
} // namespace } // namespace
void SymbolizedFrame::set(const std::shared_ptr<ElfFile>& file, void SymbolizedFrame::set(
const std::shared_ptr<ElfFile>& file,
uintptr_t address, uintptr_t address,
Dwarf::LocationInfoMode mode) { Dwarf::LocationInfoMode mode) {
clear(); clear();
...@@ -79,10 +80,10 @@ void SymbolizedFrame::set(const std::shared_ptr<ElfFile>& file, ...@@ -79,10 +80,10 @@ void SymbolizedFrame::set(const std::shared_ptr<ElfFile>& file,
} }
Symbolizer::Symbolizer(ElfCacheBase* cache, Dwarf::LocationInfoMode mode) 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, void Symbolizer::symbolize(
const uintptr_t* addresses,
SymbolizedFrame* frames, SymbolizedFrame* frames,
size_t addrCount) { size_t addrCount) {
size_t remaining = 0; size_t remaining = 0;
...@@ -110,8 +111,7 @@ void Symbolizer::symbolize(const uintptr_t* addresses, ...@@ -110,8 +111,7 @@ void Symbolizer::symbolize(const uintptr_t* addresses,
} }
selfPath[selfSize] = '\0'; selfPath[selfSize] = '\0';
for (auto lmap = _r_debug.r_map; for (auto lmap = _r_debug.r_map; lmap != nullptr && remaining != 0;
lmap != nullptr && remaining != 0;
lmap = lmap->l_next) { lmap = lmap->l_next) {
// The empty string is used in place of the filename for the link_map // The empty string is used in place of the filename for the link_map
// corresponding to the running executable. Additionally, the `l_addr' is // corresponding to the running executable. Additionally, the `l_addr' is
...@@ -129,9 +129,8 @@ void Symbolizer::symbolize(const uintptr_t* addresses, ...@@ -129,9 +129,8 @@ void Symbolizer::symbolize(const uintptr_t* addresses,
// header for the running executable, since its `l_addr' is zero, but we // 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 // should use `l_addr' for everything else---in particular, if the object
// is position-independent, getBaseAddress() (which is p_vaddr) will be 0. // is position-independent, getBaseAddress() (which is p_vaddr) will be 0.
auto const base = lmap->l_addr != 0 auto const base =
? lmap->l_addr lmap->l_addr != 0 ? lmap->l_addr : elfFile->getBaseAddress();
: elfFile->getBaseAddress();
for (size_t i = 0; i < addrCount && remaining != 0; ++i) { for (size_t i = 0; i < addrCount && remaining != 0; ++i) {
auto& frame = frames[i]; auto& frame = frames[i];
...@@ -186,7 +185,9 @@ void SymbolizePrinter::print(uintptr_t address, const SymbolizedFrame& frame) { ...@@ -186,7 +185,9 @@ void SymbolizePrinter::print(uintptr_t address, const SymbolizedFrame& frame) {
return; return;
} }
SCOPE_EXIT { color(Color::DEFAULT); }; SCOPE_EXIT {
color(Color::DEFAULT);
};
if (!(options_ & NO_FRAME_ADDRESS)) { if (!(options_ & NO_FRAME_ADDRESS)) {
color(kAddressColor); color(kAddressColor);
...@@ -196,8 +197,8 @@ void SymbolizePrinter::print(uintptr_t address, const SymbolizedFrame& frame) { ...@@ -196,8 +197,8 @@ void SymbolizePrinter::print(uintptr_t address, const SymbolizedFrame& frame) {
} }
const char padBuf[] = " "; const char padBuf[] = " ";
folly::StringPiece pad(padBuf, folly::StringPiece pad(
sizeof(padBuf) - 1 - (16 - 2 * sizeof(uintptr_t))); padBuf, sizeof(padBuf) - 1 - (16 - 2 * sizeof(uintptr_t)));
color(kFunctionColor); color(kFunctionColor);
if (!frame.found) { if (!frame.found) {
...@@ -245,8 +246,7 @@ void SymbolizePrinter::print(uintptr_t address, const SymbolizedFrame& frame) { ...@@ -245,8 +246,7 @@ void SymbolizePrinter::print(uintptr_t address, const SymbolizedFrame& frame) {
} }
void SymbolizePrinter::color(SymbolizePrinter::Color color) { void SymbolizePrinter::color(SymbolizePrinter::Color color) {
if ((options_ & COLOR) == 0 && if ((options_ & COLOR) == 0 && ((options_ & COLOR_IF_TTY) == 0 || !isTty_)) {
((options_ & COLOR_IF_TTY) == 0 || !isTty_)) {
return; return;
} }
if (color < 0 || color >= kColorMap.size()) { if (color < 0 || color >= kColorMap.size()) {
...@@ -255,13 +255,15 @@ void SymbolizePrinter::color(SymbolizePrinter::Color color) { ...@@ -255,13 +255,15 @@ void SymbolizePrinter::color(SymbolizePrinter::Color color) {
doPrint(kColorMap[color]); doPrint(kColorMap[color]);
} }
void SymbolizePrinter::println(uintptr_t address, void SymbolizePrinter::println(
uintptr_t address,
const SymbolizedFrame& frame) { const SymbolizedFrame& frame) {
print(address, frame); print(address, frame);
doPrint("\n"); doPrint("\n");
} }
void SymbolizePrinter::printTerse(uintptr_t address, void SymbolizePrinter::printTerse(
uintptr_t address,
const SymbolizedFrame& frame) { const SymbolizedFrame& frame) {
if (frame.found && frame.name && frame.name[0] != '\0') { if (frame.found && frame.name && frame.name[0] != '\0') {
char demangledBuf[2048] = {0}; char demangledBuf[2048] = {0};
...@@ -282,7 +284,8 @@ void SymbolizePrinter::printTerse(uintptr_t address, ...@@ -282,7 +284,8 @@ void SymbolizePrinter::printTerse(uintptr_t address,
} }
} }
void SymbolizePrinter::println(const uintptr_t* addresses, void SymbolizePrinter::println(
const uintptr_t* addresses,
const SymbolizedFrame* frames, const SymbolizedFrame* frames,
size_t frameCount) { size_t frameCount) {
for (size_t i = 0; i < frameCount; ++i) { for (size_t i = 0; i < frameCount; ++i) {
...@@ -315,8 +318,8 @@ int getFD(const std::ios& stream) { ...@@ -315,8 +318,8 @@ int getFD(const std::ios& stream) {
bool isColorfulTty(int options, int fd) { bool isColorfulTty(int options, int fd) {
if ((options & SymbolizePrinter::TERSE) != 0 || if ((options & SymbolizePrinter::TERSE) != 0 ||
(options & SymbolizePrinter::COLOR_IF_TTY) == 0 || (options & SymbolizePrinter::COLOR_IF_TTY) == 0 || fd < 0 ||
fd < 0 || !::isatty(fd)) { !::isatty(fd)) {
return false; return false;
} }
auto term = ::getenv("TERM"); auto term = ::getenv("TERM");
...@@ -327,8 +330,7 @@ bool isColorfulTty(int options, int fd) { ...@@ -327,8 +330,7 @@ bool isColorfulTty(int options, int fd) {
OStreamSymbolizePrinter::OStreamSymbolizePrinter(std::ostream& out, int options) OStreamSymbolizePrinter::OStreamSymbolizePrinter(std::ostream& out, int options)
: SymbolizePrinter(options, isColorfulTty(options, getFD(out))), : SymbolizePrinter(options, isColorfulTty(options, getFD(out))),
out_(out) { out_(out) {}
}
void OStreamSymbolizePrinter::doPrint(StringPiece sp) { void OStreamSymbolizePrinter::doPrint(StringPiece sp) {
out_ << sp; out_ << sp;
...@@ -337,8 +339,7 @@ void OStreamSymbolizePrinter::doPrint(StringPiece sp) { ...@@ -337,8 +339,7 @@ void OStreamSymbolizePrinter::doPrint(StringPiece sp) {
FDSymbolizePrinter::FDSymbolizePrinter(int fd, int options, size_t bufferSize) FDSymbolizePrinter::FDSymbolizePrinter(int fd, int options, size_t bufferSize)
: SymbolizePrinter(options, isColorfulTty(options, fd)), : SymbolizePrinter(options, isColorfulTty(options, fd)),
fd_(fd), fd_(fd),
buffer_(bufferSize ? IOBuf::create(bufferSize) : nullptr) { buffer_(bufferSize ? IOBuf::create(bufferSize) : nullptr) {}
}
FDSymbolizePrinter::~FDSymbolizePrinter() { FDSymbolizePrinter::~FDSymbolizePrinter() {
flush(); flush();
...@@ -367,8 +368,7 @@ void FDSymbolizePrinter::flush() { ...@@ -367,8 +368,7 @@ void FDSymbolizePrinter::flush() {
FILESymbolizePrinter::FILESymbolizePrinter(FILE* file, int options) FILESymbolizePrinter::FILESymbolizePrinter(FILE* file, int options)
: SymbolizePrinter(options, isColorfulTty(options, fileno(file))), : SymbolizePrinter(options, isColorfulTty(options, fileno(file))),
file_(file) { file_(file) {}
}
void FILESymbolizePrinter::doPrint(StringPiece sp) { void FILESymbolizePrinter::doPrint(StringPiece sp) {
fwrite(sp.data(), 1, sp.size(), file_); fwrite(sp.data(), 1, sp.size(), file_);
......
...@@ -39,13 +39,16 @@ class Symbolizer; ...@@ -39,13 +39,16 @@ class Symbolizer;
* Frame information: symbol name and location. * Frame information: symbol name and location.
*/ */
struct SymbolizedFrame { struct SymbolizedFrame {
SymbolizedFrame() { } SymbolizedFrame() {}
void set(const std::shared_ptr<ElfFile>& file, void set(
const std::shared_ptr<ElfFile>& file,
uintptr_t address, uintptr_t address,
Dwarf::LocationInfoMode mode); Dwarf::LocationInfoMode mode);
void clear() { *this = SymbolizedFrame(); } void clear() {
*this = SymbolizedFrame();
}
bool found = false; bool found = false;
const char* name = nullptr; const char* name = nullptr;
...@@ -64,7 +67,7 @@ struct SymbolizedFrame { ...@@ -64,7 +67,7 @@ struct SymbolizedFrame {
template <size_t N> template <size_t N>
struct FrameArray { struct FrameArray {
FrameArray() { } FrameArray() {}
size_t frameCount = 0; size_t frameCount = 0;
uintptr_t addresses[N]; uintptr_t addresses[N];
...@@ -117,13 +120,15 @@ class Symbolizer { ...@@ -117,13 +120,15 @@ class Symbolizer {
explicit Symbolizer(Dwarf::LocationInfoMode mode = kDefaultLocationInfoMode) explicit Symbolizer(Dwarf::LocationInfoMode mode = kDefaultLocationInfoMode)
: Symbolizer(nullptr, mode) {} : Symbolizer(nullptr, mode) {}
explicit Symbolizer(ElfCacheBase* cache, explicit Symbolizer(
ElfCacheBase* cache,
Dwarf::LocationInfoMode mode = kDefaultLocationInfoMode); Dwarf::LocationInfoMode mode = kDefaultLocationInfoMode);
/** /**
* Symbolize given addresses. * Symbolize given addresses.
*/ */
void symbolize(const uintptr_t* addresses, void symbolize(
const uintptr_t* addresses,
SymbolizedFrame* frames, SymbolizedFrame* frames,
size_t frameCount); size_t frameCount);
...@@ -181,27 +186,30 @@ class SymbolizePrinter { ...@@ -181,27 +186,30 @@ class SymbolizePrinter {
/** /**
* Print multiple addresses on separate lines. * Print multiple addresses on separate lines.
*/ */
void println(const uintptr_t* addresses, void println(
const uintptr_t* addresses,
const SymbolizedFrame* frames, const SymbolizedFrame* frames,
size_t frameCount); size_t frameCount);
/** /**
* Print a string, no endling newline. * 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 * Print multiple addresses on separate lines, skipping the first
* skip addresses. * skip addresses.
*/ */
template <size_t N> template <size_t N>
void println(const FrameArray<N>& fa, size_t skip=0) { void println(const FrameArray<N>& fa, size_t skip = 0) {
if (skip < fa.frameCount) { if (skip < fa.frameCount) {
println(fa.addresses + skip, fa.frames + skip, fa.frameCount - skip); println(fa.addresses + skip, fa.frames + skip, fa.frameCount - skip);
} }
} }
virtual ~SymbolizePrinter() { } virtual ~SymbolizePrinter() {}
enum Options { enum Options {
// Skip file and line information // Skip file and line information
...@@ -226,9 +234,7 @@ class SymbolizePrinter { ...@@ -226,9 +234,7 @@ class SymbolizePrinter {
protected: protected:
explicit SymbolizePrinter(int options, bool isTty = false) explicit SymbolizePrinter(int options, bool isTty = false)
: options_(options), : options_(options), isTty_(isTty) {}
isTty_(isTty) {
}
const int options_; const int options_;
const bool isTty_; const bool isTty_;
...@@ -255,7 +261,8 @@ class SymbolizePrinter { ...@@ -255,7 +261,8 @@ class SymbolizePrinter {
*/ */
class OStreamSymbolizePrinter : public SymbolizePrinter { class OStreamSymbolizePrinter : public SymbolizePrinter {
public: public:
explicit OStreamSymbolizePrinter(std::ostream& out, int options=0); explicit OStreamSymbolizePrinter(std::ostream& out, int options = 0);
private: private:
void doPrint(StringPiece sp) override; void doPrint(StringPiece sp) override;
std::ostream& out_; std::ostream& out_;
...@@ -267,10 +274,10 @@ class OStreamSymbolizePrinter : public SymbolizePrinter { ...@@ -267,10 +274,10 @@ class OStreamSymbolizePrinter : public SymbolizePrinter {
*/ */
class FDSymbolizePrinter : public SymbolizePrinter { class FDSymbolizePrinter : public SymbolizePrinter {
public: public:
explicit FDSymbolizePrinter(int fd, int options=0, explicit FDSymbolizePrinter(int fd, int options = 0, size_t bufferSize = 0);
size_t bufferSize=0);
~FDSymbolizePrinter() override; ~FDSymbolizePrinter() override;
void flush(); void flush();
private: private:
void doPrint(StringPiece sp) override; void doPrint(StringPiece sp) override;
...@@ -284,7 +291,8 @@ class FDSymbolizePrinter : public SymbolizePrinter { ...@@ -284,7 +291,8 @@ class FDSymbolizePrinter : public SymbolizePrinter {
*/ */
class FILESymbolizePrinter : public SymbolizePrinter { class FILESymbolizePrinter : public SymbolizePrinter {
public: public:
explicit FILESymbolizePrinter(FILE* file, int options=0); explicit FILESymbolizePrinter(FILE* file, int options = 0);
private: private:
void doPrint(StringPiece sp) override; void doPrint(StringPiece sp) override;
FILE* const file_ = nullptr; FILE* const file_ = nullptr;
...@@ -296,11 +304,18 @@ class FILESymbolizePrinter : public SymbolizePrinter { ...@@ -296,11 +304,18 @@ class FILESymbolizePrinter : public SymbolizePrinter {
*/ */
class StringSymbolizePrinter : public SymbolizePrinter { class StringSymbolizePrinter : public SymbolizePrinter {
public: public:
explicit StringSymbolizePrinter(int options=0) : SymbolizePrinter(options) { } explicit StringSymbolizePrinter(int options = 0)
: SymbolizePrinter(options) {}
std::string str() const { return buf_.toStdString(); } std::string str() const {
const fbstring& fbstr() const { return buf_; } return buf_.toStdString();
fbstring moveFbString() { return std::move(buf_); } }
const fbstring& fbstr() const {
return buf_;
}
fbstring moveFbString() {
return std::move(buf_);
}
private: private:
void doPrint(StringPiece sp) override; void doPrint(StringPiece sp) override;
......
...@@ -47,52 +47,11 @@ void checkPath( ...@@ -47,52 +47,11 @@ void checkPath(
} }
TEST(Dwarf, Path) { 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( checkPath(
"hello.cpp", "/hello.cpp", "/", "", "hello.cpp", "/./././././././", "", "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");
} }
...@@ -29,8 +29,7 @@ class ElfTest : public ::testing::Test { ...@@ -29,8 +29,7 @@ class ElfTest : public ::testing::Test {
// Path to the test binary itself; set by main() // Path to the test binary itself; set by main()
static std::string binaryPath; static std::string binaryPath;
ElfTest() : elfFile_(binaryPath.c_str()) { ElfTest() : elfFile_(binaryPath.c_str()) {}
}
~ElfTest() override {} ~ElfTest() override {}
protected: protected:
...@@ -41,17 +40,15 @@ std::string ElfTest::binaryPath; ...@@ -41,17 +40,15 @@ std::string ElfTest::binaryPath;
TEST_F(ElfTest, IntegerValue) { TEST_F(ElfTest, IntegerValue) {
auto sym = elfFile_.getSymbolByName("kIntegerValue"); auto sym = elfFile_.getSymbolByName("kIntegerValue");
EXPECT_NE(nullptr, sym.first) << EXPECT_NE(nullptr, sym.first) << "Failed to look up symbol kIntegerValue";
"Failed to look up symbol kIntegerValue";
EXPECT_EQ(kIntegerValue, elfFile_.getSymbolValue<uint64_t>(sym.second)); EXPECT_EQ(kIntegerValue, elfFile_.getSymbolValue<uint64_t>(sym.second));
} }
TEST_F(ElfTest, PointerValue) { TEST_F(ElfTest, PointerValue) {
auto sym = elfFile_.getSymbolByName("kStringValue"); auto sym = elfFile_.getSymbolByName("kStringValue");
EXPECT_NE(nullptr, sym.first) << EXPECT_NE(nullptr, sym.first) << "Failed to look up symbol kStringValue";
"Failed to look up symbol kStringValue";
ElfW(Addr) addr = elfFile_.getSymbolValue<ElfW(Addr)>(sym.second); ElfW(Addr) addr = elfFile_.getSymbolValue<ElfW(Addr)>(sym.second);
const char *str = &elfFile_.getAddressValue<const char>(addr); const char* str = &elfFile_.getAddressValue<const char>(addr);
EXPECT_STREQ(kStringValue, str); EXPECT_STREQ(kStringValue, str);
} }
......
...@@ -22,7 +22,9 @@ ...@@ -22,7 +22,9 @@
#include <folly/experimental/TestUtil.h> #include <folly/experimental/TestUtil.h>
#include <folly/portability/GTest.h> #include <folly/portability/GTest.h>
namespace folly { namespace symbolizer { namespace test { namespace folly {
namespace symbolizer {
namespace test {
using folly::test::TemporaryFile; using folly::test::TemporaryFile;
...@@ -34,7 +36,8 @@ void writeAll(int fd, const char* str) { ...@@ -34,7 +36,8 @@ void writeAll(int fd, const char* str) {
void expect(LineReader& lr, const char* expected) { void expect(LineReader& lr, const char* expected) {
StringPiece line; StringPiece line;
size_t expectedLen = strlen(expected); size_t expectedLen = strlen(expected);
EXPECT_EQ(expectedLen != 0 ? LineReader::kReading : LineReader::kEof, EXPECT_EQ(
expectedLen != 0 ? LineReader::kReading : LineReader::kEof,
lr.readLine(line)); lr.readLine(line));
EXPECT_EQ(expectedLen, line.size()); EXPECT_EQ(expectedLen, line.size());
EXPECT_EQ(std::string(expected, expectedLen), line.str()); EXPECT_EQ(std::string(expected, expectedLen), line.str());
...@@ -43,7 +46,8 @@ void expect(LineReader& lr, const char* expected) { ...@@ -43,7 +46,8 @@ void expect(LineReader& lr, const char* expected) {
TEST(LineReader, Simple) { TEST(LineReader, Simple) {
TemporaryFile file; TemporaryFile file;
int fd = file.fd(); int fd = file.fd();
writeAll(fd, writeAll(
fd,
"Meow\n" "Meow\n"
"Hello world\n" "Hello world\n"
"This is a long line. It is longer than the other lines.\n" "This is a long line. It is longer than the other lines.\n"
...@@ -81,5 +85,6 @@ TEST(LineReader, Simple) { ...@@ -81,5 +85,6 @@ TEST(LineReader, Simple) {
expect(lr, ""); expect(lr, "");
} }
} }
} // namespace test
}}} // namespaces } // namespace symbolizer
} // namespace folly
...@@ -22,7 +22,9 @@ ...@@ -22,7 +22,9 @@
#include <folly/Range.h> #include <folly/Range.h>
#include <folly/portability/GTest.h> #include <folly/portability/GTest.h>
namespace folly { namespace symbolizer { namespace test { namespace folly {
namespace symbolizer {
namespace test {
namespace { namespace {
...@@ -30,7 +32,6 @@ void print(StringPiece sp) { ...@@ -30,7 +32,6 @@ void print(StringPiece sp) {
writeFull(STDERR_FILENO, sp.data(), sp.size()); writeFull(STDERR_FILENO, sp.data(), sp.size());
} }
void callback1() { void callback1() {
print("Callback1\n"); print("Callback1\n");
} }
...@@ -73,9 +74,9 @@ TEST(SignalHandler, Simple) { ...@@ -73,9 +74,9 @@ TEST(SignalHandler, Simple) {
"Callback2\n"); "Callback2\n");
#endif #endif
} }
} // namespace test
} // namespace symbolizer
}}} // namespaces } // namespace folly
// Can't use initFacebookLight since that would install its own signal handlers // Can't use initFacebookLight since that would install its own signal handlers
// Can't use initFacebookNoSignals since we cannot depend on common // Can't use initFacebookNoSignals since we cannot depend on common
......
...@@ -16,10 +16,13 @@ ...@@ -16,10 +16,13 @@
#pragma once #pragma once
namespace folly { namespace symbolizer { namespace test { namespace folly {
namespace symbolizer {
namespace test {
inline void failHard() { inline void failHard() {
*(/* nolint */ volatile char*)42; // SIGSEGV *(/* nolint */ volatile char*)42; // SIGSEGV
} }
} // namespace test
}}} // namespaces } // namespace symbolizer
} // namespace folly
...@@ -89,7 +89,7 @@ TEST(StackTraceTest, Signal) { ...@@ -89,7 +89,7 @@ TEST(StackTraceTest, Signal) {
EXPECT_TRUE(handled); EXPECT_TRUE(handled);
} }
int main(int argc, char *argv[]) { int main(int argc, char* argv[]) {
testing::InitGoogleTest(&argc, argv); testing::InitGoogleTest(&argc, argv);
gflags::ParseCommandLineFlags(&argc, &argv, true); gflags::ParseCommandLineFlags(&argc, &argv, true);
google::InitGoogleLogging(argv[0]); google::InitGoogleLogging(argv[0]);
......
...@@ -22,10 +22,11 @@ ...@@ -22,10 +22,11 @@
#include <folly/String.h> #include <folly/String.h>
#include <folly/portability/GTest.h> #include <folly/portability/GTest.h>
namespace folly { namespace symbolizer { namespace test { namespace folly {
namespace symbolizer {
namespace test {
void foo() { void foo() {}
}
TEST(Symbolizer, Single) { TEST(Symbolizer, Single) {
Symbolizer symbolizer; Symbolizer symbolizer;
...@@ -36,11 +37,11 @@ TEST(Symbolizer, Single) { ...@@ -36,11 +37,11 @@ TEST(Symbolizer, Single) {
// The version of clang we use doesn't generate a `.debug_aranges` section, // The version of clang we use doesn't generate a `.debug_aranges` section,
// which the symbolizer needs to lookup the filename. // which the symbolizer needs to lookup the filename.
constexpr bool built_with_clang = constexpr bool built_with_clang =
#ifdef __clang__ #ifdef __clang__
true; true;
#else #else
false; false;
#endif #endif
if (!built_with_clang) { if (!built_with_clang) {
auto path = a.location.file.toString(); auto path = a.location.file.toString();
folly::StringPiece basename(path); folly::StringPiece basename(path);
...@@ -113,8 +114,9 @@ TEST_F(ElfCacheTest, SignalSafeElfCache) { ...@@ -113,8 +114,9 @@ TEST_F(ElfCacheTest, SignalSafeElfCache) {
runElfCacheTest(symbolizer); runElfCacheTest(symbolizer);
} }
} }
} // namespace test
}}} // namespaces } // namespace symbolizer
} // namespace folly
// Can't use initFacebookLight since that would install its own signal handlers // Can't use initFacebookLight since that would install its own signal handlers
// Can't use initFacebookNoSignals since we cannot depend on common // Can't use initFacebookNoSignals since we cannot depend on common
......
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