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 {
*/
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 <address, file, line> tuple
END, // End of sequence
CONTINUE, // Continue feeding opcodes
COMMIT, // Commit new <address, file, line> 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<uint64_t, folly::StringPiece> 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
......@@ -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 <class Fn>
const ElfW(Shdr)* ElfFile::iterateSections(Fn fn) const {
const ElfW(Shdr)* ptr = &at<ElfW(Shdr)>(elfHeader().e_shoff);
const ElfShdr* ElfFile::iterateSections(Fn fn) const {
const ElfShdr* ptr = &at<ElfShdr>(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 <class Fn>
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 <class Fn>
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 <class Fn>
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<ElfW(Sym)>(section.sh_offset);
const ElfW(Sym)* end = sym + (section.sh_size / section.sh_entsize);
const ElfSym* sym = &at<ElfSym>(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 <class Fn>
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
This diff is collapsed.
......@@ -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<ElfW(Ehdr)>(0);
const ElfEhdr& elfHeader() const {
return at<ElfEhdr>(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 <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.
......@@ -117,14 +128,14 @@ class ElfFile {
* true, or nullptr if fn returned false for all sections.
*/
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
* iterateSections(), but filtered only for sections with the given type.
*/
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.
......@@ -133,10 +144,10 @@ class ElfFile {
* or nullptr if fn returned false for all symbols.
*/
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>
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<const ElfW(Shdr)*, const ElfW(Sym)*> Symbol;
typedef std::pair<const ElfShdr*, const ElfSym*> Symbol;
Symbol getDefinitionByAddress(uintptr_t address) const;
/**
......@@ -162,8 +173,8 @@ class ElfFile {
* Get the value of a symbol.
*/
template <class T>
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<T>(*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<ElfW(Addr)>(sym.second);
* auto addr = getSymbolValue<ElfAddr>(sym.second);
* const char* str = &getSymbolValue<const char>(addr);
*/
template <class T>
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<T>(*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 <class T>
const typename std::enable_if<std::is_pod<T>::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<std::is_pod<T>::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<T*>(file_ + offset);
}
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
// 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<T>(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 <folly/experimental/symbolizer/Elf-inl.h>
......@@ -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<ElfFile> SignalSafeElfCache::getFile(StringPiece p) {
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::lock_guard<std::mutex> lock(mutex_);
......@@ -129,5 +130,5 @@ std::shared_ptr<ElfFile> ElfCache::filePtr(const std::shared_ptr<Entry>& e) {
// share ownership
return std::shared_ptr<ElfFile>(e, &e->file);
}
}} // namespaces
} // namespace symbolizer
} // namespace folly
......@@ -33,7 +33,8 @@
#include <folly/Range.h>
#include <folly/experimental/symbolizer/Elf.h>
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<ElfFile> 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<Entry, LruLink, &Entry::lruLink>,
boost::intrusive::constant_time_size<false>> LruList;
boost::intrusive::constant_time_size<false>>
LruList;
LruList lruList_;
};
}} // namespaces
} // namespace symbolizer
} // namespace folly
......@@ -14,7 +14,6 @@
* limitations under the License.
*/
#include <folly/experimental/symbolizer/Elf.h>
#include <stdio.h>
......@@ -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<uintptr_t>(main));
......
......@@ -20,20 +20,20 @@
#include <folly/FileUtil.h>
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<char*>(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
......@@ -22,7 +22,8 @@
#include <folly/Range.h>
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
......@@ -37,7 +37,8 @@
#include <folly/portability/SysSyscall.h>
#include <folly/portability/Unistd.h>
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<std::mutex> 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<std::mutex> 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<bool> 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
......@@ -18,7 +18,8 @@
#include <functional>
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
......@@ -20,11 +20,12 @@
#define UNW_LOCAL_ONLY 1
#include <libunwind.h>
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
......@@ -19,7 +19,8 @@
#include <cstdint>
#include <cstdlib>
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
......@@ -58,11 +58,12 @@ ElfCache* defaultElfCache() {
return cache;
}
} // namespace
} // namespace
void SymbolizedFrame::set(const std::shared_ptr<ElfFile>& file,
uintptr_t address,
Dwarf::LocationInfoMode mode) {
void SymbolizedFrame::set(
const std::shared_ptr<ElfFile>& file,
uintptr_t address,
Dwarf::LocationInfoMode mode) {
clear();
found = true;
......@@ -79,12 +80,12 @@ void SymbolizedFrame::set(const std::shared_ptr<ElfFile>& 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<const char*, SymbolizePrinter::Color::NUM>
......@@ -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
......@@ -39,13 +39,16 @@ class Symbolizer;
* Frame information: symbol name and location.
*/
struct SymbolizedFrame {
SymbolizedFrame() { }
SymbolizedFrame() {}
void set(const std::shared_ptr<ElfFile>& file,
uintptr_t address,
Dwarf::LocationInfoMode mode);
void set(
const std::shared_ptr<ElfFile>& 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 <size_t N>
struct FrameArray {
FrameArray() { }
FrameArray() {}
size_t frameCount = 0;
uintptr_t addresses[N];
......@@ -90,7 +93,7 @@ bool fixFrameArray(FrameArray<N>& 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 <size_t N>
void symbolize(FrameArray<N>& 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 <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) {
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<FrameArray<kMaxStackTraceDepth>> addresses_;
};
} // namespace symbolizer
} // namespace folly
} // namespace symbolizer
} // namespace folly
......@@ -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");
}
......@@ -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<uint64_t>(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<ElfW(Addr)>(sym.second);
const char *str = &elfFile_.getAddressValue<const char>(addr);
const char* str = &elfFile_.getAddressValue<const char>(addr);
EXPECT_STREQ(kStringValue, str);
}
......
......@@ -22,7 +22,9 @@
#include <folly/experimental/TestUtil.h>
#include <folly/portability/GTest.h>
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
......@@ -22,7 +22,9 @@
#include <folly/Range.h>
#include <folly/portability/GTest.h>
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
......
......@@ -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
......@@ -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]);
......
......@@ -22,10 +22,11 @@
#include <folly/String.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) {
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
......
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