void dirtySymbols(SymbolMap &map, const Set<uint32_t> &dirty) { SymbolMap::iterator it = map.begin(); while (it != map.end()) { if (dirty.contains(it->first.fileId())) { map.erase(it++); } else { it->second->dirty(dirty); ++it; } } }
static void LoadSymbols() { butil::Timer tm; tm.start(); butil::ScopedFILE fp(fopen("/proc/self/maps", "r")); if (fp == NULL) { return; } char* line = NULL; size_t line_len = 0; ssize_t nr = 0; while ((nr = getline(&line, &line_len, fp.get())) != -1) { butil::StringSplitter sp(line, line + line_len, ' '); if (sp == NULL) { continue; } char* endptr; uintptr_t start_addr = strtoull(sp.field(), &endptr, 16); if (*endptr != '-') { continue; } ++endptr; uintptr_t end_addr = strtoull(endptr, &endptr, 16); if (*endptr != ' ') { continue; } ++sp; // ..x. must be executable if (sp == NULL || sp.length() != 4 || sp.field()[2] != 'x') { continue; } ++sp; if (sp == NULL) { continue; } size_t offset = strtoull(sp.field(), &endptr, 16); if (*endptr != ' ') { continue; } //skip $4~$5 for (int i = 0; i < 3; ++i) { ++sp; } if (sp == NULL) { continue; } size_t n = sp.length(); if (sp.field()[n-1] == '\n') { --n; } std::string path(sp.field(), n); if (!HasExt(path, ".so") && !HasExt(path, ".dll") && !HasExt(path, ".dylib") && !HasExt(path, ".bundle")) { continue; } LibInfo info; info.start_addr = start_addr; info.end_addr = end_addr; info.offset = offset; info.path = path; ExtractSymbolsFromBinary(symbol_map, info); } free(line); LibInfo info; info.start_addr = 0; info.end_addr = std::numeric_limits<uintptr_t>::max(); info.offset = 0; info.path = program_invocation_name; ExtractSymbolsFromBinary(symbol_map, info); butil::Timer tm2; tm2.start(); size_t num_removed = 0; bool last_is_empty = false; for (SymbolMap::iterator it = symbol_map.begin(); it != symbol_map.end();) { if (it->second.empty()) { if (last_is_empty) { symbol_map.erase(it++); ++num_removed; } else { ++it; } last_is_empty = true; } else { ++it; } } tm2.stop(); RPC_VLOG_IF(num_removed) << "Removed " << num_removed << " entries in " << tm2.m_elapsed() << "ms"; tm.stop(); RPC_VLOG << "Loaded all symbols in " << tm.m_elapsed() << "ms"; }