Commit 4d966258 authored by Tudor Bosman's avatar Tudor Bosman Committed by Dave Watson

Unbreak Symbolizer with small ElfCache

Test Plan: fbconfig -r folly/experimental/symbolizer && fbmake runtests_opt && fbmake runtests

Reviewed By: simpkins@fb.com

FB internal diff: D1224552

@override-unit-failures
parent 7f4c8868
...@@ -57,11 +57,9 @@ std::shared_ptr<ElfFile> SignalSafeElfCache::getFile(StringPiece p) { ...@@ -57,11 +57,9 @@ std::shared_ptr<ElfFile> SignalSafeElfCache::getFile(StringPiece p) {
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) {
auto path = p.str();
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
auto pos = files_.find(path); auto pos = files_.find(p);
if (pos != files_.end()) { if (pos != files_.end()) {
// Found, move to back (MRU) // Found, move to back (MRU)
auto& entry = pos->second; auto& entry = pos->second;
...@@ -71,6 +69,8 @@ std::shared_ptr<ElfFile> ElfCache::getFile(StringPiece p) { ...@@ -71,6 +69,8 @@ std::shared_ptr<ElfFile> ElfCache::getFile(StringPiece p) {
} }
auto entry = std::make_shared<Entry>(); auto entry = std::make_shared<Entry>();
entry->path = p.str();
auto& path = entry->path;
// No negative caching // No negative caching
if (entry->file.openNoThrow(path.c_str()) == -1) { if (entry->file.openNoThrow(path.c_str()) == -1) {
...@@ -78,11 +78,12 @@ std::shared_ptr<ElfFile> ElfCache::getFile(StringPiece p) { ...@@ -78,11 +78,12 @@ std::shared_ptr<ElfFile> ElfCache::getFile(StringPiece p) {
} }
if (files_.size() == capacity_) { if (files_.size() == capacity_) {
// Evict LRU auto& e = lruList_.front();
lruList_.pop_front(); lruList_.pop_front();
files_.erase(e.path);
} }
files_.emplace(std::move(path), entry); files_.emplace(entry->path, entry);
lruList_.push_back(*entry); lruList_.push_back(*entry);
return filePtr(entry); return filePtr(entry);
......
...@@ -107,7 +107,9 @@ class ElfCache : public ElfCacheBase { ...@@ -107,7 +107,9 @@ class ElfCache : public ElfCacheBase {
std::mutex mutex_; std::mutex mutex_;
typedef boost::intrusive::list_member_hook<> LruLink; typedef boost::intrusive::list_member_hook<> LruLink;
struct Entry { struct Entry {
std::string path;
ElfFile file; ElfFile file;
LruLink lruLink; LruLink lruLink;
}; };
...@@ -115,7 +117,10 @@ class ElfCache : public ElfCacheBase { ...@@ -115,7 +117,10 @@ class ElfCache : public ElfCacheBase {
static std::shared_ptr<ElfFile> filePtr(const std::shared_ptr<Entry>& e); static std::shared_ptr<ElfFile> filePtr(const std::shared_ptr<Entry>& e);
size_t capacity_; size_t capacity_;
std::unordered_map<std::string, std::shared_ptr<Entry>> files_; std::unordered_map<
StringPiece,
std::shared_ptr<Entry>,
StringPieceHash> files_;
typedef boost::intrusive::list< typedef boost::intrusive::list<
Entry, Entry,
......
...@@ -160,6 +160,27 @@ ElfCache* defaultElfCache() { ...@@ -160,6 +160,27 @@ ElfCache* defaultElfCache() {
} // namespace } // namespace
void SymbolizedFrame::set(const std::shared_ptr<ElfFile>& file,
uintptr_t address) {
clear();
found = true;
address += file->getBaseAddress();
auto sym = file->getDefinitionByAddress(address);
if (!sym.first) {
return;
}
file_ = file;
auto name = file->getSymbolName(sym);
if (name) {
this->name = name;
}
Dwarf(file.get()).findAddress(address, location);
}
Symbolizer::Symbolizer(ElfCacheBase* cache) Symbolizer::Symbolizer(ElfCacheBase* cache)
: cache_(cache ?: defaultElfCache()) { : cache_(cache ?: defaultElfCache()) {
} }
...@@ -172,8 +193,7 @@ void Symbolizer::symbolize(const uintptr_t* addresses, ...@@ -172,8 +193,7 @@ void Symbolizer::symbolize(const uintptr_t* addresses,
auto& frame = frames[i]; auto& frame = frames[i];
if (!frame.found) { if (!frame.found) {
++remaining; ++remaining;
frame.name.clear(); frame.clear();
frame.location = Dwarf::LocationInfo();
} }
} }
...@@ -234,17 +254,7 @@ void Symbolizer::symbolize(const uintptr_t* addresses, ...@@ -234,17 +254,7 @@ void Symbolizer::symbolize(const uintptr_t* addresses,
} }
// Undo relocation // Undo relocation
uintptr_t fileAddress = address - from + elfFile->getBaseAddress(); frame.set(elfFile, address - from);
auto sym = elfFile->getDefinitionByAddress(fileAddress);
if (!sym.first) {
continue;
}
auto name = elfFile->getSymbolName(sym);
if (name) {
frame.name = name;
}
Dwarf(elfFile.get()).findAddress(fileAddress, frame.location);
} }
} }
......
...@@ -32,14 +32,17 @@ ...@@ -32,14 +32,17 @@
namespace folly { namespace folly {
namespace symbolizer { namespace symbolizer {
class Symbolizer;
/** /**
* Frame information: symbol name and location. * Frame information: symbol name and location.
*
* Note that both name and location are references in the Symbolizer object,
* which must outlive this SymbolizedFrame object.
*/ */
struct SymbolizedFrame { struct SymbolizedFrame {
SymbolizedFrame() : found(false) { } SymbolizedFrame() : found(false) { }
void set(const std::shared_ptr<ElfFile>& file, uintptr_t address);
void clear() { *this = SymbolizedFrame(); }
bool isSignalFrame; bool isSignalFrame;
bool found; bool found;
StringPiece name; StringPiece name;
...@@ -51,6 +54,8 @@ struct SymbolizedFrame { ...@@ -51,6 +54,8 @@ struct SymbolizedFrame {
fbstring demangledName() const { fbstring demangledName() const {
return demangle(name.fbstr().c_str()); return demangle(name.fbstr().c_str());
} }
private:
std::shared_ptr<ElfFile> file_;
}; };
template <size_t N> template <size_t N>
......
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