ElfCache::ElfCache(size_t capacity) : capacity_(capacity) { }
std::shared_ptr<ElfFile> ElfCache::getFile(StringPiece p) {
- auto path = p.str();
-
std::lock_guard<std::mutex> lock(mutex_);
- auto pos = files_.find(path);
+ auto pos = files_.find(p);
if (pos != files_.end()) {
// Found, move to back (MRU)
auto& entry = pos->second;
}
auto entry = std::make_shared<Entry>();
+ entry->path = p.str();
+ auto& path = entry->path;
// No negative caching
if (entry->file.openNoThrow(path.c_str()) == -1) {
}
if (files_.size() == capacity_) {
- // Evict LRU
+ auto& e = lruList_.front();
lruList_.pop_front();
+ files_.erase(e.path);
}
- files_.emplace(std::move(path), entry);
+ files_.emplace(entry->path, entry);
lruList_.push_back(*entry);
return filePtr(entry);
std::mutex mutex_;
typedef boost::intrusive::list_member_hook<> LruLink;
+
struct Entry {
+ std::string path;
ElfFile file;
LruLink lruLink;
};
static std::shared_ptr<ElfFile> filePtr(const std::shared_ptr<Entry>& e);
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<
Entry,
} // 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)
: cache_(cache ?: defaultElfCache()) {
}
auto& frame = frames[i];
if (!frame.found) {
++remaining;
- frame.name.clear();
- frame.location = Dwarf::LocationInfo();
+ frame.clear();
}
}
}
// Undo relocation
- uintptr_t fileAddress = address - from + elfFile->getBaseAddress();
- 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);
+ frame.set(elfFile, address - from);
}
}
namespace folly {
namespace symbolizer {
+class Symbolizer;
+
/**
* 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 {
SymbolizedFrame() : found(false) { }
+
+ void set(const std::shared_ptr<ElfFile>& file, uintptr_t address);
+ void clear() { *this = SymbolizedFrame(); }
+
bool isSignalFrame;
bool found;
StringPiece name;
fbstring demangledName() const {
return demangle(name.fbstr().c_str());
}
+ private:
+ std::shared_ptr<ElfFile> file_;
};
template <size_t N>