This group is locked. No changes can be made to the group while it is locked.
Date
1 - 2 of 2
[PATCH] Report proper module on kernel backtrace
Yonghong Song
Jiri,
toggle quoted message
Show quoted text
Thanks for fixing the issue. Could you submit the patch as a pull request? The pull request is the standard bcc review mechanism. Yonghong On Mon, Jul 22, 2019 at 1:36 AM Jiri Olsa <jolsa@...> wrote:
|
Jiri Olsa
Raghavendra Rao reported that memleak does not display
proper name of the related kernel module, but just the "kernel" string, like here for xfs module functions: 131072 bytes in 4 allocations from stack .. bvec_alloc+0x92 [kernel] bio_alloc_bioset+0x13f [kernel] xfs_add_to_ioend+0x2df [kernel] xfs_do_writepage+0x148 [kernel] write_cache_pages+0x171 [kernel] xfs_vm_writepages+0x59 [kernel] do_writepages+0x43 [kernel] ... The kernel resolver code is parsing /proc/kallsyms, which already has the module information in. This patch is adding support to parse the module info from /proc/kallsyms and initialize the module with proper value. Above memleak backtrace now looks like: 131072 bytes in 4 allocations from stack bvec_alloc+0x92 [kernel] bio_alloc_bioset+0x13f [kernel] xfs_add_to_ioend+0x2df [xfs] xfs_do_writepage+0x148 [xfs] write_cache_pages+0x171 [kernel] xfs_vm_writepages+0x59 [xfs] do_writepages+0x43 [kernel] ... Reported-by: Raghavendra Rao <ragrao@...> Signed-off-by: Jiri Olsa <jolsa@...> --- src/cc/bcc_proc.c | 20 ++++++++++++++++++-- src/cc/bcc_proc.h | 2 +- src/cc/bcc_syms.cc | 8 ++++---- src/cc/libbpf | 2 +- src/cc/syms.h | 5 +++-- tests/cc/test_c_api.cc | 2 +- 6 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/cc/bcc_proc.c b/src/cc/bcc_proc.c index c8f4041ed27b..d6e17282eed6 100644 --- a/src/cc/bcc_proc.c +++ b/src/cc/bcc_proc.c @@ -208,7 +208,7 @@ done: =20 int bcc_procutils_each_ksym(bcc_procutils_ksymcb callback, void *payload= ) { char line[2048]; - char *symname, *endsym; + char *symname, *endsym, *modname, *endmod =3D NULL; FILE *kallsyms; unsigned long long addr; =20 @@ -237,7 +237,23 @@ int bcc_procutils_each_ksym(bcc_procutils_ksymcb cal= lback, void *payload) { while (*endsym && !isspace(*endsym)) endsym++; *endsym =3D '\0'; =20 - callback(symname, addr, payload); + // Parse module name if it's available + modname =3D endsym + 1; + while (*modname && isspace(*endsym)) modname++; + + if (*modname && *modname =3D=3D '[') { + endmod =3D ++modname; + while (*endmod && *endmod !=3D ']') endmod++; + if (*endmod) + *(endmod) =3D '\0'; + else + endmod =3D NULL; + } + + if (!endmod) + modname =3D "kernel"; + + callback(symname, modname, addr, payload); } =20 fclose(kallsyms); diff --git a/src/cc/bcc_proc.h b/src/cc/bcc_proc.h index a56f680d5f56..368f27d9e0c3 100644 --- a/src/cc/bcc_proc.h +++ b/src/cc/bcc_proc.h @@ -42,7 +42,7 @@ typedef struct mod_info { typedef int (*bcc_procutils_modulecb)(mod_info *, int, void *); =20 // Symbol name, address, payload -typedef void (*bcc_procutils_ksymcb)(const char *, uint64_t, void *); +typedef void (*bcc_procutils_ksymcb)(const char *, const char *, uint64_= t, void *); =20 char *bcc_procutils_which_so(const char *libname, int pid); char *bcc_procutils_which(const char *binpath); diff --git a/src/cc/bcc_syms.cc b/src/cc/bcc_syms.cc index a946fe1a1048..95ec8bad398a 100644 --- a/src/cc/bcc_syms.cc +++ b/src/cc/bcc_syms.cc @@ -47,9 +47,9 @@ bool ProcStat::is_stale() { ProcStat::ProcStat(int pid) : procfs_(tfm::format("/proc/%d/exe", pid)), inode_(getinode_()) {} =20 -void KSyms::_add_symbol(const char *symname, uint64_t addr, void *p) { +void KSyms::_add_symbol(const char *symname, const char *modname, uint64= _t addr, void *p) { KSyms *ks =3D static_cast<KSyms *>(p); - ks->syms_.emplace_back(symname, addr); + ks->syms_.emplace_back(symname, modname, addr); } =20 void KSyms::refresh() { @@ -67,13 +67,13 @@ bool KSyms::resolve_addr(uint64_t addr, struct bcc_sy= mbol *sym, bool demangle) { if (syms_.empty()) goto unknown_symbol; =20 - it =3D std::upper_bound(syms_.begin(), syms_.end(), Symbol("", addr)); + it =3D std::upper_bound(syms_.begin(), syms_.end(), Symbol("", "", add= r)); if (it !=3D syms_.begin()) { it--; sym->name =3D (*it).name.c_str(); if (demangle) sym->demangle_name =3D sym->name; - sym->module =3D "kernel"; + sym->module =3D (*it).mod.c_str(); sym->offset =3D addr - (*it).addr; return true; } diff --git a/src/cc/libbpf b/src/cc/libbpf index 45ad8626010b..33b017498543 160000 --- a/src/cc/libbpf +++ b/src/cc/libbpf @@ -1 +1 @@ -Subproject commit 45ad8626010b384306bc277c46a4107f21414b22 +Subproject commit 33b017498543167b65fa948d3a0267794c78787f diff --git a/src/cc/syms.h b/src/cc/syms.h index 351da1dffbf4..021b28aa4c3a 100644 --- a/src/cc/syms.h +++ b/src/cc/syms.h @@ -50,8 +50,9 @@ public: =20 class KSyms : SymbolCache { struct Symbol { - Symbol(const char *name, uint64_t addr) : name(name), addr(addr) {} + Symbol(const char *name, const char *mod, uint64_t addr) : name(name= ), mod(mod), addr(addr) {} std::string name; + std::string mod; uint64_t addr; =20 bool operator<(const Symbol &rhs) const { return addr < rhs.addr; } @@ -59,7 +60,7 @@ class KSyms : SymbolCache { =20 std::vector<Symbol> syms_; std::unordered_map<std::string, uint64_t> symnames_; - static void _add_symbol(const char *, uint64_t, void *); + static void _add_symbol(const char *, const char *, uint64_t, void *); =20 public: virtual bool resolve_addr(uint64_t addr, struct bcc_symbol *sym, bool = demangle =3D true) override; diff --git a/tests/cc/test_c_api.cc b/tests/cc/test_c_api.cc index 8b96c649b65c..e3744be4e16a 100644 --- a/tests/cc/test_c_api.cc +++ b/tests/cc/test_c_api.cc @@ -67,7 +67,7 @@ TEST_CASE("binary resolution with `which`", "[c_api]") = { free(ld); } =20 -static void _test_ksym(const char *sym, uint64_t addr, void *_) { +static void _test_ksym(const char *sym, const char *mod, uint64_t addr, = void *_) { if (!strcmp(sym, "startup_64")) REQUIRE(addr !=3D 0x0ull); } --=20 2.21.0 |