mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
perf dwarf-aux: Fix libdw segmentation fault in cu_walk_functions_at
A segmentation fault was observed in `libdw` when running `perf kmem` with `--page stat` on some workloads. The crash occurred deep inside `libdw` (specifically in `dwarf_child` and `dwarf_diename`) when processing DWARF information. The root cause was improper error handling of `dwarf_getfuncs` in `die_find_realfunc` and `die_find_tailfunc`. `dwarf_getfuncs` returns: - `0` on success (when all functions have been processed). - A positive offset if the callback aborts early (e.g., via `DWARF_CB_ABORT` when a match is found). - `-1` on error. The original code used `if (!dwarf_getfuncs(...)) return NULL;`. On error (`-1`), `!-1` evaluates to `0` (false), bypassing the error check. Execution then proceeded as if a match was found, returning uninitialized stack memory (`die_mem`) to the caller (`cu_walk_functions_at`). When `cu_walk_functions_at` passed this uninitialized memory to `libdw` via `dwarf_diename`, it caused a segmentation fault. Fix this by correcting the error check to `if (dwarf_getfuncs(...) <= 0)`. Fixes:e0d153c690("perf-probe: Move dwarf library routines to dwarf-aux.{c, h}") Fixes:d4c537e6bf("perf probe: Ignore tail calls to probed functions") Assisted-by: Gemini-CLI:Google Gemini 3 Signed-off-by: Ian Rogers <irogers@google.com> Acked-by: Namhyung Kim <namhyung@kernel.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@linaro.org> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Zecheng Li <zli94@ncsu.edu> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
74fe02ce12
commit
d37a546770
|
|
@ -171,7 +171,6 @@ int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr,
|
|||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -620,7 +619,7 @@ Dwarf_Die *die_find_tailfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
|
|||
ad.addr = addr;
|
||||
ad.die_mem = die_mem;
|
||||
/* dwarf_getscopes can't find subprogram. */
|
||||
if (!dwarf_getfuncs(cu_die, __die_search_func_tail_cb, &ad, 0))
|
||||
if (dwarf_getfuncs(cu_die, __die_search_func_tail_cb, &ad, 0) <= 0)
|
||||
return NULL;
|
||||
else
|
||||
return die_mem;
|
||||
|
|
@ -659,7 +658,7 @@ Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
|
|||
ad.addr = addr;
|
||||
ad.die_mem = die_mem;
|
||||
/* dwarf_getscopes can't find subprogram. */
|
||||
if (!dwarf_getfuncs(cu_die, __die_search_func_cb, &ad, 0))
|
||||
if (dwarf_getfuncs(cu_die, __die_search_func_cb, &ad, 0) <= 0)
|
||||
return NULL;
|
||||
else
|
||||
return die_mem;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user