Exemple #1
0
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;
        }
    }
}
Exemple #2
0
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";
}