Skip to content

Commit

Permalink
Use bcc_symbol_option in bcc_resolve_symname
Browse files Browse the repository at this point in the history
This commit makes `bcc_resolve_symname` to take an `bcc_symbol_option`
parameter, and pass it to underlying calls to control symboling behavior.
When `NULL` is passed, it will fallback to default which is current
behavior that uses debug file, verify debug file CRC, and check all
types of symbols.

This commit also removes the unneccesary intermediate
`bcc_find_symbol_addr`.

Added documentation for usage of the API, updated most call sites to use
default with `NULL`, and fixed some memory leaks at call sites.
  • Loading branch information
palmtenor committed May 20, 2017
1 parent 36e7d54 commit aff6ce7
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 37 deletions.
3 changes: 2 additions & 1 deletion src/cc/BPF.cc
Original file line number Diff line number Diff line change
Expand Up @@ -469,8 +469,9 @@ StatusTuple BPF::unload_func(const std::string& func_name) {
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",
Expand Down
45 changes: 24 additions & 21 deletions src/cc/bcc_syms.cc
Original file line number Diff line number Diff line change
Expand Up @@ -438,21 +438,6 @@ int bcc_resolve_global_addr(int pid, const char *module, const uint64_t address,
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;
Expand All @@ -473,17 +458,32 @@ int bcc_foreach_function_symbol(const char *module, SYM_CB cb) {
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 {
Expand All @@ -501,8 +501,11 @@ int bcc_resolve_symname(const char *module, const char *symname,
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)
Expand Down
17 changes: 15 additions & 2 deletions src/cc/bcc_syms.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,22 @@ int bcc_resolve_global_addr(int pid, const char *module, const uint64_t address,
// 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);
Expand Down
6 changes: 4 additions & 2 deletions src/cc/usdt_args.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@ bool Argument::get_global_address(uint64_t *address, const std::string &binpath,
}

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;
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/lua/bcc/libbcc.lua
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ struct bcc_symbol_option {
};

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);
Expand Down
2 changes: 1 addition & 1 deletion src/lua/bcc/sym.lua
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ end
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
Expand Down
13 changes: 7 additions & 6 deletions src/python/bcc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
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
Expand Down Expand Up @@ -607,11 +607,12 @@ def _check_path_symbol(cls, module, symname, addr, pid):
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)
Expand Down
2 changes: 1 addition & 1 deletion src/python/bcc/libbcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ class bcc_symbol_option(ct.Structure):

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
Expand Down
4 changes: 2 additions & 2 deletions tests/cc/test_c_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ TEST_CASE("file-backed mapping identification") {
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);
Expand All @@ -102,7 +102,7 @@ TEST_CASE("resolve symbol name in external library", "[c_api]") {
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);
Expand Down

0 comments on commit aff6ce7

Please sign in to comment.