diff --git a/src/cc/bcc_elf.c b/src/cc/bcc_elf.c index d6cfe134c8fb..65e0e53c262c 100644 --- a/src/cc/bcc_elf.c +++ b/src/cc/bcc_elf.c @@ -291,7 +291,7 @@ static int list_in_scn(Elf *e, Elf_Scn *section, size_t stridx, size_t symsize, #endif int ret; - if (callback_lazy) + if (option->lazy_symbolize) ret = callback_lazy(stridx, sym.st_name, name_len, sym.st_value, sym.st_size, debugfile, payload); else @@ -585,14 +585,16 @@ static int foreach_sym_core(const char *path, bcc_elf_symcb callback, int bcc_elf_foreach_sym(const char *path, bcc_elf_symcb callback, void *option, void *payload) { - return foreach_sym_core( - path, callback, NULL, (struct bcc_symbol_option*)option, payload, 0); + struct bcc_symbol_option *o = option; + o->lazy_symbolize = 0; + return foreach_sym_core(path, callback, NULL, o, payload, 0); } int bcc_elf_foreach_sym_lazy(const char *path, bcc_elf_symcb_lazy callback, void *option, void *payload) { - return foreach_sym_core(path, NULL, callback, - (struct bcc_symbol_option*)option, payload, 0); + struct bcc_symbol_option *o = option; + o->lazy_symbolize = 1; + return foreach_sym_core(path, NULL, callback, o, payload, 0); } int bcc_elf_get_text_scn_info(const char *path, uint64_t *addr, diff --git a/src/cc/bcc_syms.cc b/src/cc/bcc_syms.cc index c14170c8159d..44bcec284ee4 100644 --- a/src/cc/bcc_syms.cc +++ b/src/cc/bcc_syms.cc @@ -110,6 +110,7 @@ ProcSyms::ProcSyms(int pid, struct bcc_symbol_option *option) symbol_option_ = { .use_debug_file = 1, .check_debug_file_crc = 1, + .lazy_symbolize = 0, .use_symbol_type = (1 << STT_FUNC) | (1 << STT_GNU_IFUNC) }; load_modules(); @@ -294,8 +295,12 @@ void ProcSyms::Module::load_sym_table() { if (type_ == ModuleType::PERF_MAP) bcc_perf_map_foreach_sym(path_.c_str(), _add_symbol, this); - if (type_ == ModuleType::EXEC || type_ == ModuleType::SO) - bcc_elf_foreach_sym_lazy(path_.c_str(), _add_symbol_lazy, symbol_option_, this); + if (type_ == ModuleType::EXEC || type_ == ModuleType::SO) { + if (symbol_option_->lazy_symbolize) + bcc_elf_foreach_sym_lazy(path_.c_str(), _add_symbol_lazy, symbol_option_, this); + else + bcc_elf_foreach_sym(path_.c_str(), _add_symbol, symbol_option_, this); + } if (type_ == ModuleType::VDSO) bcc_elf_foreach_vdso_sym(_add_symbol, this); @@ -399,18 +404,19 @@ bool ProcSyms::Module::find_addr(uint64_t offset, struct bcc_symbol *sym) { for (; offset >= it->start; --it) { if (offset < it->start + it->size) { // Resolve and cache the symbol name if necessary - if (!it->name) { + if (!it->is_name_resolved) { ProcMountNSGuard g(mount_ns_); - std::string sym_name(it->name_idx.str_len + 1, '\0'); - if (bcc_elf_symbol_str(name_.c_str(), it->name_idx.section_idx, - it->name_idx.str_table_idx, &sym_name[0], sym_name.size(), - it->name_idx.debugfile)) + std::string sym_name(it->data.name_idx.str_len + 1, '\0'); + if (bcc_elf_symbol_str(name_.c_str(), it->data.name_idx.section_idx, + it->data.name_idx.str_table_idx, &sym_name[0], sym_name.size(), + it->data.name_idx.debugfile)) break; - it->name = &*(symnames_.emplace(std::move(sym_name)).first); + it->data.name = &*(symnames_.emplace(std::move(sym_name)).first); + it->is_name_resolved = true; } - sym->name = it->name->c_str(); + sym->name = it->data.name->c_str(); sym->offset = (offset - it->start); return true; } @@ -667,6 +673,7 @@ int bcc_foreach_function_symbol(const char *module, SYM_CB cb) { static struct bcc_symbol_option default_option = { .use_debug_file = 1, .check_debug_file_crc = 1, + .lazy_symbolize = 0, .use_symbol_type = (1 << STT_FUNC) | (1 << STT_GNU_IFUNC) }; @@ -705,6 +712,7 @@ int bcc_resolve_symname(const char *module, const char *symname, static struct bcc_symbol_option default_option = { .use_debug_file = 1, .check_debug_file_crc = 1, + .lazy_symbolize = 0, #if defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ .use_symbol_type = BCC_SYM_ALL_TYPES | (1 << STT_PPC64LE_SYM_LEP), #else diff --git a/src/cc/bcc_syms.h b/src/cc/bcc_syms.h index 12b3cfad8be6..054e4812f682 100644 --- a/src/cc/bcc_syms.h +++ b/src/cc/bcc_syms.h @@ -47,6 +47,8 @@ static const uint32_t BCC_SYM_ALL_TYPES = 65535; struct bcc_symbol_option { int use_debug_file; int check_debug_file_crc; + // Symbolize on-demand or symbolize everything ahead of time + int lazy_symbolize; // Bitmask flags indicating what types of ELF symbols to use uint32_t use_symbol_type; }; diff --git a/src/cc/syms.h b/src/cc/syms.h index e8b22c78c42b..351da1dffbf4 100644 --- a/src/cc/syms.h +++ b/src/cc/syms.h @@ -78,17 +78,22 @@ class ProcSyms : SymbolCache { struct Symbol { Symbol(const std::string *name, uint64_t start, uint64_t size) - : name(name), start(start), size(size) {} + : is_name_resolved(true), start(start), size(size) { + data.name = name; + } Symbol(size_t section_idx, size_t str_table_idx, size_t str_len, uint64_t start, uint64_t size, bool debugfile) - : start(start), size(size) { - name_idx.section_idx = section_idx; - name_idx.str_table_idx = str_table_idx; - name_idx.str_len = str_len; - name_idx.debugfile = debugfile; + : is_name_resolved(false), start(start), size(size) { + data.name_idx.section_idx = section_idx; + data.name_idx.str_table_idx = str_table_idx; + data.name_idx.str_len = str_len; + data.name_idx.debugfile = debugfile; } - struct NameIdx name_idx; - const std::string *name{nullptr}; + bool is_name_resolved; + union { + struct NameIdx name_idx; + const std::string *name{nullptr}; + } data; uint64_t start; uint64_t size;