Commit 81654bf7 authored by Paul Chaignon's avatar Paul Chaignon

cc: Dynamically allocate memory for library path

parent 893ad2fc
...@@ -197,8 +197,6 @@ static struct ld_lib { ...@@ -197,8 +197,6 @@ static struct ld_lib {
int flags; int flags;
} * lib_cache; } * lib_cache;
static char libpath[4096];
static int read_cache1(const char *ld_map) { static int read_cache1(const char *ld_map) {
struct ld_cache1 *ldcache = (struct ld_cache1 *)ld_map; struct ld_cache1 *ldcache = (struct ld_cache1 *)ld_map;
const char *ldstrings = const char *ldstrings =
...@@ -310,7 +308,7 @@ static bool match_so_flags(int flags) { ...@@ -310,7 +308,7 @@ static bool match_so_flags(int flags) {
return true; return true;
} }
static bool which_so_in_process(const char* libname, int pid) { static bool which_so_in_process(const char* libname, int pid, char* libpath) {
int ret, found = false; int ret, found = false;
char endline[4096], *mapname = NULL, *newline; char endline[4096], *mapname = NULL, *newline;
char mappings_file[128]; char mappings_file[128];
...@@ -341,7 +339,7 @@ static bool which_so_in_process(const char* libname, int pid) { ...@@ -341,7 +339,7 @@ static bool which_so_in_process(const char* libname, int pid) {
if (strstr(mapname, ".so") && (strstr(mapname, search1) || if (strstr(mapname, ".so") && (strstr(mapname, search1) ||
strstr(mapname, search2))) { strstr(mapname, search2))) {
found = true; found = true;
memcpy(libpath, mapname, strlen(mapname)); memcpy(libpath, mapname, strlen(mapname) + 1);
break; break;
} }
} while (ret != EOF); } while (ret != EOF);
...@@ -350,16 +348,17 @@ static bool which_so_in_process(const char* libname, int pid) { ...@@ -350,16 +348,17 @@ static bool which_so_in_process(const char* libname, int pid) {
return found; return found;
} }
const char *bcc_procutils_which_so(const char *libname, int pid) { char *bcc_procutils_which_so(const char *libname, int pid) {
const size_t soname_len = strlen(libname) + strlen("lib.so"); const size_t soname_len = strlen(libname) + strlen("lib.so");
char soname[soname_len + 1]; char soname[soname_len + 1];
char libpath[4096];
int i; int i;
if (strchr(libname, '/')) if (strchr(libname, '/'))
return libname; return strdup(libname);
if (pid && which_so_in_process(libname, pid)) if (pid && which_so_in_process(libname, pid, libpath))
return libpath; return strdup(libpath);
if (lib_cache_count < 0) if (lib_cache_count < 0)
return NULL; return NULL;
...@@ -374,8 +373,12 @@ const char *bcc_procutils_which_so(const char *libname, int pid) { ...@@ -374,8 +373,12 @@ const char *bcc_procutils_which_so(const char *libname, int pid) {
for (i = 0; i < lib_cache_count; ++i) { for (i = 0; i < lib_cache_count; ++i) {
if (!strncmp(lib_cache[i].libname, soname, soname_len) && if (!strncmp(lib_cache[i].libname, soname, soname_len) &&
match_so_flags(lib_cache[i].flags)) { match_so_flags(lib_cache[i].flags)) {
return lib_cache[i].path; return strdup(lib_cache[i].path);
} }
} }
return NULL; return NULL;
} }
void bcc_procutils_free(const char *ptr) {
free((void *)ptr);
}
...@@ -27,11 +27,12 @@ extern "C" { ...@@ -27,11 +27,12 @@ extern "C" {
typedef int (*bcc_procutils_modulecb)(const char *, uint64_t, uint64_t, void *); typedef int (*bcc_procutils_modulecb)(const char *, uint64_t, uint64_t, void *);
typedef void (*bcc_procutils_ksymcb)(const char *, uint64_t, void *); typedef void (*bcc_procutils_ksymcb)(const char *, uint64_t, void *);
const char *bcc_procutils_which_so(const char *libname, int pid); char *bcc_procutils_which_so(const char *libname, int pid);
char *bcc_procutils_which(const char *binpath); char *bcc_procutils_which(const char *binpath);
int bcc_procutils_each_module(int pid, bcc_procutils_modulecb callback, int bcc_procutils_each_module(int pid, bcc_procutils_modulecb callback,
void *payload); void *payload);
int bcc_procutils_each_ksym(bcc_procutils_ksymcb callback, void *payload); int bcc_procutils_each_ksym(bcc_procutils_ksymcb callback, void *payload);
void bcc_procutils_free(const char *ptr);
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -315,7 +315,7 @@ int bcc_resolve_symname(const char *module, const char *symname, ...@@ -315,7 +315,7 @@ int bcc_resolve_symname(const char *module, const char *symname,
return -1; return -1;
if (strchr(module, '/')) { if (strchr(module, '/')) {
sym->module = module; sym->module = strdup(module);
} else { } else {
sym->module = bcc_procutils_which_so(module, pid); sym->module = bcc_procutils_which_so(module, pid);
} }
......
...@@ -223,8 +223,9 @@ std::string Context::resolve_bin_path(const std::string &bin_path) { ...@@ -223,8 +223,9 @@ std::string Context::resolve_bin_path(const std::string &bin_path) {
if (char *which = bcc_procutils_which(bin_path.c_str())) { if (char *which = bcc_procutils_which(bin_path.c_str())) {
result = which; result = which;
::free(which); ::free(which);
} else if (const char *which_so = bcc_procutils_which_so(bin_path.c_str(), 0)) { } else if (char *which_so = bcc_procutils_which_so(bin_path.c_str(), 0)) {
result = which_so; result = which_so;
::free(which_so);
} }
return result; return result;
......
...@@ -110,6 +110,7 @@ struct bcc_symbol { ...@@ -110,6 +110,7 @@ struct bcc_symbol {
int bcc_resolve_symname(const char *module, const char *symname, const uint64_t addr, 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 *sym);
void bcc_procutils_free(const char *ptr);
void *bcc_symcache_new(int pid); void *bcc_symcache_new(int pid);
int bcc_symcache_resolve(void *symcache, uint64_t addr, struct bcc_symbol *sym); int bcc_symcache_resolve(void *symcache, uint64_t addr, struct bcc_symbol *sym);
void bcc_symcache_refresh(void *resolver); void bcc_symcache_refresh(void *resolver);
......
...@@ -32,15 +32,20 @@ end ...@@ -32,15 +32,20 @@ end
local function check_path_symbol(module, symname, addr) local function check_path_symbol(module, symname, addr)
local sym = SYM() local sym = SYM()
local module_path
if libbcc.bcc_resolve_symname(module, symname, addr or 0x0, 0, sym) < 0 then if libbcc.bcc_resolve_symname(module, symname, addr or 0x0, 0, sym) < 0 then
if sym[0].module == nil then if sym[0].module == nil then
error("could not find library '%s' in the library path" % module) error("could not find library '%s' in the library path" % module)
else else
module_path = ffi.string(sym[0].module)
libbcc.bcc_procutils_free(sym[0].module)
error("failed to resolve symbol '%s' in '%s'" % { error("failed to resolve symbol '%s' in '%s'" % {
symname, ffi.string(sym[0].module)}) symname, module_path})
end end
end end
return ffi.string(sym[0].module), sym[0].offset module_path = ffi.string(sym[0].module)
libbcc.bcc_procutils_free(sym[0].module)
return module_path, sym[0].offset
end end
return { create_cache=create_cache, check_path_symbol=check_path_symbol } return { create_cache=create_cache, check_path_symbol=check_path_symbol }
...@@ -562,13 +562,20 @@ class BPF(object): ...@@ -562,13 +562,20 @@ class BPF(object):
symname.encode("ascii"), addr or 0x0, c_pid, psym) < 0: symname.encode("ascii"), addr or 0x0, c_pid, psym) < 0:
if not sym.module: if not sym.module:
raise Exception("could not find library %s" % module) raise Exception("could not find library %s" % module)
lib.bcc_procutils_free(sym.module)
raise Exception("could not determine address of symbol %s" % symname) raise Exception("could not determine address of symbol %s" % symname)
return sym.module.decode(), sym.offset module_path = ct.cast(sym.module, ct.c_char_p).value.decode()
lib.bcc_procutils_free(sym.module)
return module_path, sym.offset
@staticmethod @staticmethod
def find_library(libname): def find_library(libname):
res = lib.bcc_procutils_which_so(libname.encode("ascii"), 0) res = lib.bcc_procutils_which_so(libname.encode("ascii"), 0)
return res if res is None else res.decode() if not res:
return None
libpath = ct.cast(res, ct.c_char_p).value.decode()
lib.bcc_procutils_free(res)
return libpath
@staticmethod @staticmethod
def get_tracepoints(tp_re): def get_tracepoints(tp_re):
......
...@@ -126,12 +126,14 @@ class bcc_symbol(ct.Structure): ...@@ -126,12 +126,14 @@ class bcc_symbol(ct.Structure):
_fields_ = [ _fields_ = [
('name', ct.c_char_p), ('name', ct.c_char_p),
('demangle_name', ct.c_char_p), ('demangle_name', ct.c_char_p),
('module', ct.c_char_p), ('module', ct.POINTER(ct.c_char)),
('offset', ct.c_ulonglong), ('offset', ct.c_ulonglong),
] ]
lib.bcc_procutils_which_so.restype = ct.c_char_p 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_which_so.argtypes = [ct.c_char_p, ct.c_int]
lib.bcc_procutils_free.restype = None
lib.bcc_procutils_free.argtypes = [ct.c_void_p]
lib.bcc_resolve_symname.restype = ct.c_int lib.bcc_resolve_symname.restype = ct.c_int
lib.bcc_resolve_symname.argtypes = [ lib.bcc_resolve_symname.argtypes = [
......
...@@ -30,17 +30,19 @@ ...@@ -30,17 +30,19 @@
using namespace std; using namespace std;
TEST_CASE("shared object resolution", "[c_api]") { TEST_CASE("shared object resolution", "[c_api]") {
const char *libm = bcc_procutils_which_so("m", 0); char *libm = bcc_procutils_which_so("m", 0);
REQUIRE(libm); REQUIRE(libm);
REQUIRE(libm[0] == '/'); REQUIRE(libm[0] == '/');
REQUIRE(string(libm).find("libm.so") != string::npos); REQUIRE(string(libm).find("libm.so") != string::npos);
free(libm);
} }
TEST_CASE("shared object resolution using loaded libraries", "[c_api]") { TEST_CASE("shared object resolution using loaded libraries", "[c_api]") {
const char *libelf = bcc_procutils_which_so("elf", getpid()); char *libelf = bcc_procutils_which_so("elf", getpid());
REQUIRE(libelf); REQUIRE(libelf);
REQUIRE(libelf[0] == '/'); REQUIRE(libelf[0] == '/');
REQUIRE(string(libelf).find("libelf") != string::npos); REQUIRE(string(libelf).find("libelf") != string::npos);
free(libelf);
} }
TEST_CASE("binary resolution with `which`", "[c_api]") { TEST_CASE("binary resolution with `which`", "[c_api]") {
...@@ -68,6 +70,7 @@ TEST_CASE("resolve symbol name in external library", "[c_api]") { ...@@ -68,6 +70,7 @@ TEST_CASE("resolve symbol name in external library", "[c_api]") {
REQUIRE(string(sym.module).find("libc.so") != string::npos); REQUIRE(string(sym.module).find("libc.so") != string::npos);
REQUIRE(sym.module[0] == '/'); REQUIRE(sym.module[0] == '/');
REQUIRE(sym.offset != 0); REQUIRE(sym.offset != 0);
bcc_procutils_free(sym.module);
} }
TEST_CASE("resolve symbol name in external library using loaded libraries", "[c_api]") { TEST_CASE("resolve symbol name in external library using loaded libraries", "[c_api]") {
...@@ -77,6 +80,7 @@ TEST_CASE("resolve symbol name in external library using loaded libraries", "[c_ ...@@ -77,6 +80,7 @@ TEST_CASE("resolve symbol name in external library using loaded libraries", "[c_
REQUIRE(string(sym.module).find("libbcc.so") != string::npos); REQUIRE(string(sym.module).find("libbcc.so") != string::npos);
REQUIRE(sym.module[0] == '/'); REQUIRE(sym.module[0] == '/');
REQUIRE(sym.offset != 0); REQUIRE(sym.offset != 0);
bcc_procutils_free(sym.module);
} }
extern "C" int _a_test_function(const char *a_string) { extern "C" int _a_test_function(const char *a_string) {
......
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