StatusTuple BPF::check_binary_symbol(const std::string& binary_path,
const std::string& symbol,
uint64_t symbol_addr, bcc_symbol* output) {
+ // TODO: Fix output.module memory leak here
int res = bcc_resolve_symname(binary_path.c_str(), symbol.c_str(),
- symbol_addr, 0, output);
+ symbol_addr, 0, nullptr, output);
if (res < 0)
return StatusTuple(
-1, "Unable to find offset for binary %s symbol %s address %lx",
return 0;
}
-static int _find_sym(const char *symname, uint64_t addr, uint64_t end,
- int flags, void *payload) {
- struct bcc_symbol *sym = (struct bcc_symbol *)payload;
- // TODO: check for actual function symbol in flags
- if (!strcmp(sym->name, symname)) {
- sym->offset = addr;
- return -1;
- }
- return 0;
-}
-
-int bcc_find_symbol_addr(struct bcc_symbol *sym) {
- return bcc_elf_foreach_sym(sym->module, _find_sym, sym);
-}
-
static int _sym_cb_wrapper(const char *symname, uint64_t addr, uint64_t end,
int flags, void *payload) {
SYM_CB cb = (SYM_CB) payload;
module, _sym_cb_wrapper, &default_option, (void *)cb);
}
+static int _find_sym(const char *symname, uint64_t addr, uint64_t end,
+ int flags, void *payload) {
+ struct bcc_symbol *sym = (struct bcc_symbol *)payload;
+ if (!strcmp(sym->name, symname)) {
+ sym->offset = addr;
+ return -1;
+ }
+ return 0;
+}
+
int bcc_resolve_symname(const char *module, const char *symname,
- const uint64_t addr, int pid, struct bcc_symbol *sym) {
+ const uint64_t addr, int pid,
+ struct bcc_symbol_option *option,
+ struct bcc_symbol *sym) {
uint64_t load_addr;
-
- sym->module = NULL;
- sym->name = NULL;
- sym->offset = 0x0;
+ static struct bcc_symbol_option default_option = {
+ .use_debug_file = 1,
+ .check_debug_file_crc = 1,
+ .use_symbol_type = BCC_SYM_ALL_TYPES,
+ };
if (module == NULL)
return -1;
+ memset(sym, 0, sizeof(bcc_symbol));
+
if (strchr(module, '/')) {
sym->module = strdup(module);
} else {
sym->name = symname;
sym->offset = addr;
+ if (option == NULL)
+ option = &default_option;
+
if (sym->name && sym->offset == 0x0)
- if (bcc_find_symbol_addr(sym) < 0)
+ if (bcc_elf_foreach_sym(sym->module, _find_sym, option, sym) < 0)
goto invalid_module;
if (sym->offset == 0x0)
// Will prefer use debug file and check debug file CRC when reading the module.
int bcc_foreach_function_symbol(const char *module, SYM_CB cb);
-int bcc_find_symbol_addr(struct bcc_symbol *sym);
+// Find the offset of a symbol in a module binary. If addr is not zero, will
+// calculate the offset using the provided addr and the module's load address.
+//
+// If pid is provided, will use it to help lookup the module in the Process and
+// enter the Process's mount Namespace.
+//
+// If option is not NULL, will respect the specified options for lookup.
+// Otherwise default option will apply, which is to use debug file, verify
+// checksum, and try all types of symbols.
+//
+// Return 0 on success and -1 on failure. Output will be write to sym. After
+// use, sym->module need to be freed if it's not empty.
int bcc_resolve_symname(const char *module, const char *symname,
- const uint64_t addr, int pid, struct bcc_symbol *sym);
+ const uint64_t addr, int pid,
+ struct bcc_symbol_option* option,
+ struct bcc_symbol *sym);
void *bcc_enter_mount_ns(int pid);
void bcc_exit_mount_ns(void **guard);
}
if (!bcc_elf_is_shared_obj(binpath.c_str())) {
- struct bcc_symbol sym = {deref_ident_->c_str(), binpath.c_str(), 0x0};
- if (!bcc_find_symbol_addr(&sym) && sym.offset) {
+ struct bcc_symbol sym;
+ if (bcc_resolve_symname(binpath.c_str(), deref_ident_->c_str(), 0x0, -1, nullptr, &sym) == 0) {
*address = sym.offset;
+ if (sym.module)
+ ::free(const_cast<char*>(sym.module));
return true;
}
}
};
int bcc_resolve_symname(const char *module, const char *symname, const uint64_t addr,
- int pid, struct bcc_symbol *sym);
+ int pid, struct bcc_symbol_option *option,
+ struct bcc_symbol *sym);
void bcc_procutils_free(const char *ptr);
void *bcc_symcache_new(int pid);
void bcc_symbol_free_demangle_name(struct bcc_symbol *sym);
local function check_path_symbol(module, symname, addr, pid)
local sym = SYM()
local module_path
- if libbcc.bcc_resolve_symname(module, symname, addr or 0x0, pid or 0, sym) < 0 then
+ if libbcc.bcc_resolve_symname(module, symname, addr or 0x0, pid or 0, nil, sym) < 0 then
if sym[0].module == nil then
error("could not find library '%s' in the library path" % module)
else
import sys
basestring = (unicode if sys.version_info[0] < 3 else str)
-from .libbcc import lib, _CB_TYPE, bcc_symbol, _SYM_CB_TYPE
+from .libbcc import lib, _CB_TYPE, bcc_symbol, bcc_symbol_option, _SYM_CB_TYPE
from .table import Table
from .perf import Perf
from .utils import get_online_cpus
sym = bcc_symbol()
psym = ct.pointer(sym)
c_pid = 0 if pid == -1 else pid
- if lib.bcc_resolve_symname(module.encode("ascii"),
- symname.encode("ascii"), addr or 0x0, c_pid, psym) < 0:
- if not sym.module:
- raise Exception("could not find library %s" % module)
- lib.bcc_procutils_free(sym.module)
+ if lib.bcc_resolve_symname(
+ module.encode("ascii"), symname.encode("ascii"),
+ addr or 0x0, c_pid,
+ ct.cast(None, ct.POINTER(bcc_symbol_option)),
+ psym,
+ ) < 0:
raise Exception("could not determine address of symbol %s" % symname)
module_path = ct.cast(sym.module, ct.c_char_p).value.decode()
lib.bcc_procutils_free(sym.module)
lib.bcc_resolve_symname.restype = ct.c_int
lib.bcc_resolve_symname.argtypes = [
- ct.c_char_p, ct.c_char_p, ct.c_ulonglong, ct.c_int, ct.POINTER(bcc_symbol)]
+ ct.c_char_p, ct.c_char_p, ct.c_ulonglong, ct.c_int, ct.POINTER(bcc_symbol_option), ct.POINTER(bcc_symbol)]
_SYM_CB_TYPE = ct.CFUNCTYPE(ct.c_int, ct.c_char_p, ct.c_ulonglong)
lib.bcc_foreach_function_symbol.restype = ct.c_int
TEST_CASE("resolve symbol name in external library", "[c_api]") {
struct bcc_symbol sym;
- REQUIRE(bcc_resolve_symname("c", "malloc", 0x0, 0, &sym) == 0);
+ REQUIRE(bcc_resolve_symname("c", "malloc", 0x0, 0, nullptr, &sym) == 0);
REQUIRE(string(sym.module).find("libc.so") != string::npos);
REQUIRE(sym.module[0] == '/');
REQUIRE(sym.offset != 0);
TEST_CASE("resolve symbol name in external library using loaded libraries", "[c_api]") {
struct bcc_symbol sym;
- REQUIRE(bcc_resolve_symname("bcc", "bcc_procutils_which", 0x0, getpid(), &sym) == 0);
+ REQUIRE(bcc_resolve_symname("bcc", "bcc_procutils_which", 0x0, getpid(), nullptr, &sym) == 0);
REQUIRE(string(sym.module).find("libbcc.so") != string::npos);
REQUIRE(sym.module[0] == '/');
REQUIRE(sym.offset != 0);