Symbolizer::Symbolizer(ElfCacheBase* cache, Dwarf::LocationInfoMode mode) : cache_(cache ? cache : defaultElfCache()), mode_(mode) { }
Symbolizer::Symbolizer(ElfCacheBase* cache) : cache_(cache ?: defaultElfCache()) { } void Symbolizer::symbolize(const uintptr_t* addresses, SymbolizedFrame* frames, size_t addressCount) { size_t remaining = 0; for (size_t i = 0; i < addressCount; ++i) { auto& frame = frames[i]; if (!frame.found) { ++remaining; frame.clear(); } } if (remaining == 0) { // we're done return; } int fd = openNoInt("/proc/self/maps", O_RDONLY); if (fd == -1) { return; } char buf[PATH_MAX + 100]; // Long enough for any line LineReader reader(fd, buf, sizeof(buf)); while (remaining != 0) { StringPiece line; if (reader.readLine(line) != LineReader::kReading) { break; } // Parse line uintptr_t from; uintptr_t to; StringPiece fileName; if (!parseProcMapsLine(line, from, to, fileName)) { continue; } bool first = true; std::shared_ptr<ElfFile> elfFile; // See if any addresses are here for (size_t i = 0; i < addressCount; ++i) { auto& frame = frames[i]; if (frame.found) { continue; } uintptr_t address = addresses[i]; if (from > address || address >= to) { continue; } // Found frame.found = true; --remaining; // Open the file on first use if (first) { first = false; elfFile = cache_->getFile(fileName); } if (!elfFile) { continue; } // Undo relocation frame.set(elfFile, address - from); } } closeNoInt(fd); }