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); }
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.name.clear(); frame.location = Dwarf::LocationInfo(); } } 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)); char fileNameBuf[PATH_MAX]; 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; ElfFile* elfFile = nullptr; // 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; if (fileCount_ < kMaxFiles && !fileName.empty() && fileName.size() < sizeof(fileNameBuf)) { memcpy(fileNameBuf, fileName.data(), fileName.size()); fileNameBuf[fileName.size()] = '\0'; auto& f = files_[fileCount_++]; if (f.openNoThrow(fileNameBuf) != -1) { elfFile = &f; } } } if (!elfFile) { continue; } // 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).findAddress(fileAddress, frame.location); } } closeNoInt(fd); }