Commit cb3d1618 authored by Brenden Blanco's avatar Brenden Blanco Committed by GitHub

Merge pull request #1164 from palmtenor/symboloptions

Add ability for users to control symboling behavior
parents 381f03db cf130834
......@@ -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",
......
......@@ -110,7 +110,7 @@ std::vector<std::string> BPFStackTable::get_stack_symbol(int stack_id,
if (pid < 0)
pid = -1;
if (pid_sym_.find(pid) == pid_sym_.end())
pid_sym_[pid] = bcc_symcache_new(pid);
pid_sym_[pid] = bcc_symcache_new(pid, nullptr);
void* cache = pid_sym_[pid];
bcc_symbol symbol;
......
......@@ -26,7 +26,10 @@
#include <gelf.h>
#include "bcc_elf.h"
#include "bcc_syms.h"
#define NT_STAPSDT 3
#define ELF_ST_TYPE(x) (((uint32_t) x) & 0xf)
static int openelf(const char *path, Elf **elf_out, int *fd_out) {
if (elf_version(EV_CURRENT) == EV_NONE)
......@@ -150,6 +153,7 @@ int bcc_elf_foreach_usdt(const char *path, bcc_elf_probecb callback,
}
static int list_in_scn(Elf *e, Elf_Scn *section, size_t stridx, size_t symsize,
struct bcc_symbol_option *option,
bcc_elf_symcb callback, void *payload) {
Elf_Data *data = NULL;
......@@ -168,8 +172,17 @@ static int list_in_scn(Elf *e, Elf_Scn *section, size_t stridx, size_t symsize,
if ((name = elf_strptr(e, stridx, sym.st_name)) == NULL)
continue;
if (name[0] == 0)
continue;
if (sym.st_value == 0)
continue;
uint32_t flag = 1 << ELF_ST_TYPE(sym.st_info);
if (!(option->use_symbol_type & flag))
continue;
if (callback(name, sym.st_value, sym.st_size, sym.st_info, payload) < 0)
if (callback(name, sym.st_value, sym.st_size, payload) < 0)
return 1; // signal termination to caller
}
}
......@@ -177,7 +190,8 @@ static int list_in_scn(Elf *e, Elf_Scn *section, size_t stridx, size_t symsize,
return 0;
}
static int listsymbols(Elf *e, bcc_elf_symcb callback, void *payload) {
static int listsymbols(Elf *e, bcc_elf_symcb callback, void *payload,
struct bcc_symbol_option *option) {
Elf_Scn *section = NULL;
while ((section = elf_nextscn(e, section)) != 0) {
......@@ -190,7 +204,7 @@ static int listsymbols(Elf *e, bcc_elf_symcb callback, void *payload) {
continue;
int rc = list_in_scn(e, section, header.sh_link, header.sh_entsize,
callback, payload);
option, callback, payload);
if (rc == 1)
break; // callback signaled termination
......@@ -347,7 +361,8 @@ static int verify_checksum(const char *file, unsigned int crc) {
return actual == crc;
}
static char *find_debug_via_debuglink(Elf *e, const char *binpath) {
static char *find_debug_via_debuglink(Elf *e, const char *binpath,
int check_crc) {
char fullpath[PATH_MAX];
char *bindir = NULL;
char *res = NULL;
......@@ -386,9 +401,9 @@ static char *find_debug_via_debuglink(Elf *e, const char *binpath) {
DONE:
free(bindir);
if (verify_checksum(res, crc))
return res;
if (check_crc && !verify_checksum(res, crc))
return NULL;
return res;
}
static char *find_debug_via_buildid(Elf *e) {
......@@ -412,11 +427,15 @@ static char *find_debug_via_buildid(Elf *e) {
}
static int foreach_sym_core(const char *path, bcc_elf_symcb callback,
void *payload, int is_debug_file) {
struct bcc_symbol_option *option, void *payload,
int is_debug_file) {
Elf *e;
int fd, res;
char *debug_file;
if (!option)
return -1;
if (openelf(path, &e, &fd) < 0)
return -1;
......@@ -424,27 +443,29 @@ static int foreach_sym_core(const char *path, bcc_elf_symcb callback,
// using the build-id section, then using the debuglink section. These are
// also the rules that GDB folows.
// See: https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html
if (!is_debug_file) {
if (option->use_debug_file && !is_debug_file) {
// The is_debug_file argument helps avoid infinitely resolving debuginfo
// files for debuginfo files and so on.
debug_file = find_debug_via_buildid(e);
if (!debug_file)
debug_file = find_debug_via_debuglink(e, path);
debug_file = find_debug_via_debuglink(e, path,
option->check_debug_file_crc);
if (debug_file) {
foreach_sym_core(debug_file, callback, payload, 1);
foreach_sym_core(debug_file, callback, option, payload, 1);
free(debug_file);
}
}
res = listsymbols(e, callback, payload);
res = listsymbols(e, callback, payload, option);
elf_end(e);
close(fd);
return res;
}
int bcc_elf_foreach_sym(const char *path, bcc_elf_symcb callback,
void *payload) {
return foreach_sym_core(path, callback, payload, 0);
void *option, void *payload) {
return foreach_sym_core(
path, callback, (struct bcc_symbol_option*)option, payload, 0);
}
static int loadaddr(Elf *e, uint64_t *addr) {
......
......@@ -34,13 +34,15 @@ struct bcc_elf_usdt {
typedef void (*bcc_elf_probecb)(const char *, const struct bcc_elf_usdt *,
void *);
typedef int (*bcc_elf_symcb)(const char *, uint64_t, uint64_t, int, void *);
// Symbol name, start address, length, payload
typedef int (*bcc_elf_symcb)(const char *, uint64_t, uint64_t, void *);
int bcc_elf_foreach_usdt(const char *path, bcc_elf_probecb callback,
void *payload);
int bcc_elf_loadaddr(const char *path, uint64_t *address);
int bcc_elf_foreach_sym(const char *path, bcc_elf_symcb callback,
void *payload);
void *option, void *payload);
int bcc_elf_get_type(const char *path);
int bcc_elf_is_shared_obj(const char *path);
......
......@@ -109,7 +109,7 @@ int bcc_perf_map_foreach_sym(const char *path, bcc_perf_map_symcb callback,
if (newline)
newline[0] = '\0';
callback(cursor, begin, len, 0, payload);
callback(cursor, begin, len, payload);
}
free(line);
......
......@@ -24,8 +24,8 @@ extern "C" {
#include <stdbool.h>
#include <unistd.h>
typedef int (*bcc_perf_map_symcb)(const char *, uint64_t, uint64_t, int,
void *);
// Symbol name, start address, length, payload
typedef int (*bcc_perf_map_symcb)(const char *, uint64_t, uint64_t, void *);
bool bcc_is_perf_map(const char *path);
......
......@@ -15,6 +15,7 @@
*/
#include <cxxabi.h>
#include <cstring>
#include <fcntl.h>
#include <linux/elf.h>
#include <string.h>
......@@ -31,6 +32,10 @@
#include "syms.h"
#include "vendor/tinyformat.hpp"
#ifndef STT_GNU_IFUNC
#define STT_GNU_IFUNC 10
#endif
ino_t ProcStat::getinode_() {
struct stat s;
return (!stat(procfs_.c_str(), &s)) ? s.st_ino : -1;
......@@ -155,8 +160,16 @@ ProcMountNSGuard::~ProcMountNSGuard() {
setns(mount_ns_->self_fd_, CLONE_NEWNS);
}
ProcSyms::ProcSyms(int pid)
ProcSyms::ProcSyms(int pid, struct bcc_symbol_option *option)
: pid_(pid), procstat_(pid), mount_ns_instance_(new ProcMountNS(pid_)) {
if (option)
std::memcpy(&symbol_option_, option, sizeof(bcc_symbol_option));
else
symbol_option_ = {
.use_debug_file = 1,
.check_debug_file_crc = 1,
.use_symbol_type = (1 << STT_FUNC) | (1 << STT_GNU_IFUNC)
};
load_modules();
}
......@@ -179,7 +192,8 @@ int ProcSyms::_add_module(const char *modname, uint64_t start, uint64_t end,
[=](const ProcSyms::Module &m) { return m.name_ == modname; });
if (it == ps->modules_.end()) {
auto module = Module(
modname, check_mount_ns ? ps->mount_ns_instance_.get() : nullptr);
modname, check_mount_ns ? ps->mount_ns_instance_.get() : nullptr,
&ps->symbol_option_);
if (module.init())
it = ps->modules_.insert(ps->modules_.end(), std::move(module));
else
......@@ -244,10 +258,12 @@ bool ProcSyms::resolve_name(const char *module, const char *name,
return false;
}
ProcSyms::Module::Module(const char *name, ProcMountNS *mount_ns)
ProcSyms::Module::Module(const char *name, ProcMountNS *mount_ns,
struct bcc_symbol_option *option)
: name_(name),
loaded_(false),
mount_ns_(mount_ns),
symbol_option_(option),
type_(ModuleType::UNKNOWN) {}
bool ProcSyms::Module::init() {
......@@ -274,10 +290,10 @@ bool ProcSyms::Module::init() {
}
int ProcSyms::Module::_add_symbol(const char *symname, uint64_t start,
uint64_t end, int flags, void *p) {
uint64_t size, void *p) {
Module *m = static_cast<Module *>(p);
auto res = m->symnames_.emplace(symname);
m->syms_.emplace_back(&*(res.first), start, end, flags);
m->syms_.emplace_back(&*(res.first), start, size);
return 0;
}
......@@ -291,7 +307,7 @@ void ProcSyms::Module::load_sym_table() {
if (type_ == ModuleType::PERF_MAP)
bcc_perf_map_foreach_sym(name_.c_str(), _add_symbol, this);
if (type_ == ModuleType::EXEC || type_ == ModuleType::SO)
bcc_elf_foreach_sym(name_.c_str(), _add_symbol, this);
bcc_elf_foreach_sym(name_.c_str(), _add_symbol, symbol_option_, this);
std::sort(syms_.begin(), syms_.end());
}
......@@ -367,10 +383,10 @@ bool ProcSyms::Module::find_addr(uint64_t offset, struct bcc_symbol *sym) {
extern "C" {
void *bcc_symcache_new(int pid) {
void *bcc_symcache_new(int pid, struct bcc_symbol_option *option) {
if (pid < 0)
return static_cast<void *>(new KSyms());
return static_cast<void *>(new ProcSyms(pid));
return static_cast<void *>(new ProcSyms(pid, option));
}
void bcc_free_symcache(void *symcache, int pid) {
......@@ -434,58 +450,52 @@ 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,
void *payload) {
SYM_CB cb = (SYM_CB) payload;
return cb(symname, addr);
}
struct sym_search_t {
struct bcc_symbol *syms;
int start;
int requested;
int *actual;
};
// see <elf.h>
#define ELF_TYPE_IS_FUNCTION(flags) (((flags) & 0xf) == 2)
int bcc_foreach_function_symbol(const char *module, SYM_CB cb) {
if (module == 0 || cb == 0)
return -1;
static int _list_sym(const char *symname, uint64_t addr, uint64_t end,
int flags, void *payload) {
if (!ELF_TYPE_IS_FUNCTION(flags) || addr == 0)
return 0;
static struct bcc_symbol_option default_option = {
.use_debug_file = 1,
.check_debug_file_crc = 1,
.use_symbol_type = (1 << STT_FUNC) | (1 << STT_GNU_IFUNC)
};
SYM_CB cb = (SYM_CB)payload;
return cb(symname, addr);
return bcc_elf_foreach_sym(
module, _sym_cb_wrapper, &default_option, (void *)cb);
}
int bcc_foreach_symbol(const char *module, SYM_CB cb) {
if (module == 0 || cb == 0)
static int _find_sym(const char *symname, uint64_t addr, uint64_t,
void *payload) {
struct bcc_symbol *sym = (struct bcc_symbol *)payload;
if (!strcmp(sym->name, symname)) {
sym->offset = addr;
return -1;
return bcc_elf_foreach_sym(module, _list_sym, (void *)cb);
}
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 {
......@@ -497,25 +507,31 @@ int bcc_resolve_symname(const char *module, const char *symname,
ProcMountNSGuard g(pid);
if (bcc_elf_loadaddr(sym->module, &load_addr) < 0) {
sym->module = NULL;
return -1;
}
if (bcc_elf_loadaddr(sym->module, &load_addr) < 0)
goto invalid_module;
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) {
sym->module = NULL;
return -1;
}
if (bcc_elf_foreach_sym(sym->module, _find_sym, option, sym) < 0)
goto invalid_module;
if (sym->offset == 0x0)
return -1;
goto invalid_module;
sym->offset = (sym->offset - load_addr);
return 0;
invalid_module:
if (sym->module) {
::free(const_cast<char*>(sym->module));
sym->module = NULL;
}
return -1;
}
void *bcc_enter_mount_ns(int pid) {
......
......@@ -31,7 +31,15 @@ struct bcc_symbol {
typedef int (*SYM_CB)(const char *symname, uint64_t addr);
void *bcc_symcache_new(int pid);
static const uint32_t BCC_SYM_ALL_TYPES = 65535;
struct bcc_symbol_option {
int use_debug_file;
int check_debug_file_crc;
// Bitmask flags indicating what types of ELF symbols to use
uint32_t use_symbol_type;
};
void *bcc_symcache_new(int pid, struct bcc_symbol_option *option);
void bcc_free_symcache(void *symcache, int pid);
// The demangle_name pointer in bcc_symbol struct is returned from the
......@@ -48,10 +56,28 @@ void bcc_symcache_refresh(void *resolver);
int bcc_resolve_global_addr(int pid, const char *module, const uint64_t address,
uint64_t *global);
int bcc_foreach_symbol(const char *module, SYM_CB cb);
int bcc_find_symbol_addr(struct bcc_symbol *sym);
// Call cb on every function symbol in the specified module. Uses simpler
// SYM_CB callback mainly for easier to use in Python API.
// 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);
// 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);
......
......@@ -24,6 +24,7 @@
#include <vector>
#include "file_desc.h"
#include "bcc_syms.h"
class ProcStat {
std::string procfs_;
......@@ -97,12 +98,11 @@ private:
class ProcSyms : SymbolCache {
struct Symbol {
Symbol(const std::string *name, uint64_t start, uint64_t size, int flags = 0)
: name(name), start(start), size(size), flags(flags) {}
Symbol(const std::string *name, uint64_t start, uint64_t size)
: name(name), start(start), size(size) {}
const std::string *name;
uint64_t start;
uint64_t size;
int flags;
bool operator<(const struct Symbol& rhs) const {
return start < rhs.start;
......@@ -123,13 +123,15 @@ class ProcSyms : SymbolCache {
Range(uint64_t s, uint64_t e) : start(s), end(e) {}
};
Module(const char *name, ProcMountNS* mount_ns);
Module(const char *name, ProcMountNS* mount_ns,
struct bcc_symbol_option *option);
bool init();
std::string name_;
std::vector<Range> ranges_;
bool loaded_;
ProcMountNS *mount_ns_;
bcc_symbol_option *symbol_option_;
ModuleType type_;
std::unordered_set<std::string> symnames_;
......@@ -141,20 +143,21 @@ class ProcSyms : SymbolCache {
bool find_addr(uint64_t offset, struct bcc_symbol *sym);
bool find_name(const char *symname, uint64_t *addr);
static int _add_symbol(const char *symname, uint64_t start, uint64_t end,
int flags, void *p);
static int _add_symbol(const char *symname, uint64_t start, uint64_t size,
void *p);
};
int pid_;
std::vector<Module> modules_;
ProcStat procstat_;
std::unique_ptr<ProcMountNS> mount_ns_instance_;
bcc_symbol_option symbol_option_;
static int _add_module(const char *, uint64_t, uint64_t, bool, void *);
bool load_modules();
public:
ProcSyms(int pid);
ProcSyms(int pid, struct bcc_symbol_option *option = nullptr);
virtual void refresh();
virtual bool resolve_addr(uint64_t addr, struct bcc_symbol *sym, bool demangle = true);
virtual bool resolve_name(const char *module, const char *name,
......
......@@ -35,14 +35,21 @@ std::string Argument::ctype() const {
bool Argument::get_global_address(uint64_t *address, const std::string &binpath,
const optional<int> &pid) const {
if (pid) {
return ProcSyms(*pid)
static struct bcc_symbol_option default_option = {
.use_debug_file = 1,
.check_debug_file_crc = 1,
.use_symbol_type = BCC_SYM_ALL_TYPES
};
return ProcSyms(*pid, &default_option)
.resolve_name(binpath.c_str(), deref_ident_->c_str(), address);
}
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;
}
}
......
......@@ -114,10 +114,17 @@ struct bcc_symbol {
uint64_t offset;
};
struct bcc_symbol_option {
int use_debug_file;
int check_debug_file_crc;
uint32_t use_symbol_type;
};
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_symcache_new(int pid, struct bcc_symbol_option *option);
void bcc_symbol_free_demangle_name(struct bcc_symbol *sym);
int bcc_symcache_resolve(void *symcache, uint64_t addr, struct bcc_symbol *sym);
void bcc_symcache_refresh(void *resolver);
......
......@@ -19,7 +19,7 @@ local SYM = ffi.typeof("struct bcc_symbol[1]")
local function create_cache(pid)
return {
_CACHE = libbcc.bcc_symcache_new(pid or -1),
_CACHE = libbcc.bcc_symcache_new(pid or -1, nil),
resolve = function(self, addr)
local sym = SYM()
if libbcc.bcc_symcache_resolve(self._CACHE, addr, sym) < 0 then
......@@ -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
......
......@@ -24,7 +24,7 @@ import errno
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
......@@ -46,7 +46,8 @@ LOG_BUFFER_SIZE = 65536
class SymbolCache(object):
def __init__(self, pid):
self.cache = lib.bcc_symcache_new(pid)
self.cache = lib.bcc_symcache_new(
pid, ct.cast(None, ct.POINTER(bcc_symbol_option)))
def resolve(self, addr, demangle):
"""
......@@ -607,11 +608,12 @@ class BPF(object):
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)
......@@ -773,7 +775,8 @@ class BPF(object):
addresses.append((dname, addr))
return 0
res = lib.bcc_foreach_symbol(name.encode('ascii'), _SYM_CB_TYPE(sym_cb))
res = lib.bcc_foreach_function_symbol(
name.encode('ascii'), _SYM_CB_TYPE(sym_cb))
if res < 0:
raise Exception("Error %d enumerating symbols in %s" % (res, name))
return addresses
......
......@@ -133,6 +133,13 @@ class bcc_symbol(ct.Structure):
('offset', ct.c_ulonglong),
]
class bcc_symbol_option(ct.Structure):
_fields_ = [
('use_debug_file', ct.c_int),
('check_debug_file_crc', ct.c_int),
('use_symbol_type', ct.c_uint),
]
lib.bcc_procutils_which_so.restype = ct.POINTER(ct.c_char)
lib.bcc_procutils_which_so.argtypes = [ct.c_char_p, ct.c_int]
lib.bcc_procutils_free.restype = None
......@@ -142,14 +149,14 @@ lib.bcc_procutils_language.argtypes = [ct.c_int]
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_symbol.restype = ct.c_int
lib.bcc_foreach_symbol.argtypes = [ct.c_char_p, _SYM_CB_TYPE]
lib.bcc_foreach_function_symbol.restype = ct.c_int
lib.bcc_foreach_function_symbol.argtypes = [ct.c_char_p, _SYM_CB_TYPE]
lib.bcc_symcache_new.restype = ct.c_void_p
lib.bcc_symcache_new.argtypes = [ct.c_int]
lib.bcc_symcache_new.argtypes = [ct.c_int, ct.POINTER(bcc_symbol_option)]
lib.bcc_free_symcache.restype = ct.c_void_p
lib.bcc_free_symcache.argtypes = [ct.c_void_p, ct.c_int]
......
......@@ -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);
......@@ -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);
......@@ -195,7 +195,7 @@ static int mntns_func(void *arg) {
TEST_CASE("resolve symbol addresses for a given PID", "[c_api]") {
struct bcc_symbol sym;
void *resolver = bcc_symcache_new(getpid());
void *resolver = bcc_symcache_new(getpid(), nullptr);
REQUIRE(resolver);
......@@ -240,7 +240,7 @@ TEST_CASE("resolve symbol addresses for a given PID", "[c_api]") {
child = spawn_child(0, true, true, mntns_func);
REQUIRE(child > 0);
void *resolver = bcc_symcache_new(child);
void *resolver = bcc_symcache_new(child, nullptr);
REQUIRE(resolver);
REQUIRE(bcc_symcache_resolve_name(resolver, "/tmp/libz.so.1", "zlibVersion",
......@@ -335,7 +335,7 @@ TEST_CASE("resolve symbols using /tmp/perf-pid.map", "[c_api]") {
child = spawn_child(map_addr, /* own_pidns */ false, false, perf_map_func);
REQUIRE(child > 0);
void *resolver = bcc_symcache_new(child);
void *resolver = bcc_symcache_new(child, nullptr);
REQUIRE(resolver);
REQUIRE(bcc_symcache_resolve(resolver, (unsigned long long)map_addr,
......@@ -355,7 +355,7 @@ TEST_CASE("resolve symbols using /tmp/perf-pid.map", "[c_api]") {
child = spawn_child(map_addr, /* own_pidns */ true, false, perf_map_func);
REQUIRE(child > 0);
void *resolver = bcc_symcache_new(child);
void *resolver = bcc_symcache_new(child, nullptr);
REQUIRE(resolver);
REQUIRE(bcc_symcache_resolve(resolver, (unsigned long long)map_addr,
......@@ -372,7 +372,7 @@ TEST_CASE("resolve symbols using /tmp/perf-pid.map", "[c_api]") {
perf_map_func_mntns);
REQUIRE(child > 0);
void *resolver = bcc_symcache_new(child);
void *resolver = bcc_symcache_new(child, nullptr);
REQUIRE(resolver);
REQUIRE(bcc_symcache_resolve(resolver, (unsigned long long)map_addr,
......@@ -391,7 +391,7 @@ TEST_CASE("resolve symbols using /tmp/perf-pid.map", "[c_api]") {
string path = perf_map_path(child);
REQUIRE(make_perf_map_file(path, (unsigned long long)map_addr) == 0);
void *resolver = bcc_symcache_new(child);
void *resolver = bcc_symcache_new(child, nullptr);
REQUIRE(resolver);
REQUIRE(bcc_symcache_resolve(resolver, (unsigned long long)map_addr,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment