Commit a0c5de1a authored by Teng Qin's avatar Teng Qin

Add file offset in bcc_procutils_each_module callback

parent 0daa9124
......@@ -81,7 +81,8 @@ int bcc_procutils_each_module(int pid, bcc_procutils_modulecb callback,
FILE *procmap;
int ret;
snprintf(procmap_filename, sizeof(procmap_filename), "/proc/%ld/maps", (long)pid);
snprintf(procmap_filename, sizeof(procmap_filename), "/proc/%ld/maps",
(long)pid);
procmap = fopen(procmap_filename, "r");
if (!procmap)
......@@ -90,10 +91,10 @@ int bcc_procutils_each_module(int pid, bcc_procutils_modulecb callback,
do {
char endline[4096];
char perm[8], dev[8];
long long begin, end, size, inode;
long long begin, end, offset, inode;
ret = fscanf(procmap, "%llx-%llx %s %llx %s %lld", &begin, &end, perm,
&size, dev, &inode);
&offset, dev, &inode);
if (!fgets(endline, sizeof(endline), procmap))
break;
......@@ -105,10 +106,12 @@ int bcc_procutils_each_module(int pid, bcc_procutils_modulecb callback,
if (newline)
newline[0] = '\0';
while (isspace(mapname[0])) mapname++;
while (isspace(mapname[0]))
mapname++;
if (strchr(perm, 'x') && bcc_mapping_is_file_backed(mapname)) {
if (callback(mapname, (uint64_t)begin, (uint64_t)end, true, payload) < 0)
if (callback(mapname, (uint64_t)begin, (uint64_t)end, (uint64_t)offset,
true, payload) < 0)
break;
}
}
......@@ -122,12 +125,15 @@ int bcc_procutils_each_module(int pid, bcc_procutils_modulecb callback,
// Try perf-<PID>.map path with process's mount namespace, chroot and NSPID,
// in case it is generated by the process itself.
if (bcc_perf_map_path(map_path, sizeof(map_path), pid))
callback(map_path, 0, -1, true, payload);
if (callback(map_path, 0, -1, 0, true, payload) < 0)
return 0;
// Try perf-<PID>.map path with global root and PID, in case it is generated
// by other Process. Avoid checking mount namespace for this.
int res = snprintf(map_path, 4096, "/tmp/perf-%d.map", pid);
if (res > 0 && res < 4096)
callback(map_path, 0, -1, false, payload);
if (callback(map_path, 0, -1, 0, false, payload) < 0)
return 0;
return 0;
}
......
......@@ -24,14 +24,21 @@ extern "C" {
#include <stdint.h>
// Module name, start address, end address, whether to check mount namespace, payload
typedef int (*bcc_procutils_modulecb)(const char *, uint64_t, uint64_t, bool, void *);
// Module name, start address, end address, file_offset,
// whether to check mount namespace, payload
// Callback returning a negative value indicates to stop the iteration
typedef int (*bcc_procutils_modulecb)(const char *, uint64_t, uint64_t,
uint64_t, bool, void *);
// Symbol name, address, payload
typedef void (*bcc_procutils_ksymcb)(const char *, uint64_t, void *);
char *bcc_procutils_which_so(const char *libname, int pid);
char *bcc_procutils_which(const char *binpath);
int bcc_mapping_is_file_backed(const char *mapname);
// Iterate over all executable memory mapping sections of a Process.
// All anonymous and non-file-backed mapping sections, namely those
// listed in bcc_mapping_is_file_backed, will be ignored.
// Returns -1 on error, and 0 on success
int bcc_procutils_each_module(int pid, bcc_procutils_modulecb callback,
void *payload);
int bcc_procutils_each_ksym(bcc_procutils_ksymcb callback, void *payload);
......
......@@ -148,7 +148,7 @@ void ProcSyms::refresh() {
}
int ProcSyms::_add_module(const char *modname, uint64_t start, uint64_t end,
bool check_mount_ns, void *payload) {
uint64_t offset, bool check_mount_ns, void *payload) {
ProcSyms *ps = static_cast<ProcSyms *>(payload);
auto it = std::find_if(
ps->modules_.begin(), ps->modules_.end(),
......@@ -403,8 +403,8 @@ struct mod_st {
uint64_t start;
};
static int _find_module(const char *modname, uint64_t start, uint64_t end, bool,
void *p) {
static int _find_module(const char *modname, uint64_t start, uint64_t end,
uint64_t offset, bool, void *p) {
struct mod_st *mod = (struct mod_st *)p;
if (!strcmp(modname, mod->name)) {
mod->start = start;
......
......@@ -130,7 +130,8 @@ class ProcSyms : SymbolCache {
static int _add_load_sections(uint64_t v_addr, uint64_t mem_sz,
uint64_t file_offset, void *payload);
static int _add_module(const char *, uint64_t, uint64_t, bool, void *);
static int _add_module(const char *, uint64_t, uint64_t, uint64_t, bool,
void *);
void load_exe();
void load_modules();
......
......@@ -207,7 +207,8 @@ class Context {
static void _each_probe(const char *binpath, const struct bcc_elf_usdt *probe,
void *p);
static int _each_module(const char *modpath, uint64_t, uint64_t, bool, void *p);
static int _each_module(const char *modpath, uint64_t, uint64_t, uint64_t,
bool, void *p);
void add_probe(const char *binpath, const struct bcc_elf_usdt *probe);
std::string resolve_bin_path(const std::string &bin_path);
......
......@@ -217,7 +217,8 @@ void Context::_each_probe(const char *binpath, const struct bcc_elf_usdt *probe,
ctx->add_probe(binpath, probe);
}
int Context::_each_module(const char *modpath, uint64_t, uint64_t, bool, void *p) {
int Context::_each_module(const char *modpath, uint64_t, uint64_t, uint64_t,
bool, void *p) {
Context *ctx = static_cast<Context *>(p);
// Modules may be reported multiple times if they contain more than one
// executable region. We are going to parse the ELF on disk anyway, so we
......
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