perf probe: Fix error propagation leading to segfault
There are two hunks in this patch that stops probe processing as soon as one error is found, breaking out of loops, the other fix an error propagation that should return a negative error number but instead was returning the result of "ret < 0", which is 1 and thus made several error checks fail because they test agains < 0. The problem could be triggered by asking for a variable that was optimized out, fact that should stop the whole probe processing but instead was segfaulting while installing broken probes: [root@emilia ~]# probe perf_mmap:55 user_lock_limit Failed to find the location of user_lock_limit at this address. Perhaps, it has been optimized out. Failed to find 'user_lock_limit' in this function. Add new events: probe:perf_mmap (on perf_mmap:55 with user_lock_limit) probe:perf_mmap_1 (on perf_mmap:55 with user_lock_limit) Segmentation fault (core dumped) [root@emilia ~]# perf probe -l probe:perf_mmap (on perf_mmap:55@git/linux/kernel/perf_event.c with user_lock_limit) probe:perf_mmap_1 (on perf_mmap:55@git/linux/kernel/perf_event.c with user_lock_limit) [root@emilia ~]# After the fix: [root@emilia ~]# probe perf_mmap:55 user_lock_limit Failed to find the location of user_lock_limit at this address. Perhaps, it has been optimized out. Failed to find 'user_lock_limit' in this function. Error: Failed to add events. (-2) [root@emilia ~]# Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Cc: Tom Zanussi <tzanussi@gmail.com> LKML-Reference: <new-submission> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
a3d1ee10d1
commit
fbee632d0c
|
@ -1832,9 +1832,12 @@ int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
|
|||
}
|
||||
|
||||
/* Loop 2: add all events */
|
||||
for (i = 0; i < npevs && ret >= 0; i++)
|
||||
for (i = 0; i < npevs && ret >= 0; i++) {
|
||||
ret = __add_probe_trace_events(pkgs[i].pev, pkgs[i].tevs,
|
||||
pkgs[i].ntevs, force_add);
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
end:
|
||||
/* Loop 3: cleanup and free trace events */
|
||||
for (i = 0; i < npevs; i++) {
|
||||
|
|
|
@ -1262,7 +1262,7 @@ static int probe_point_line_walker(const char *fname, int lineno,
|
|||
ret = call_probe_finder(NULL, pf);
|
||||
|
||||
/* Continue if no error, because the line will be in inline function */
|
||||
return ret < 0 ?: 0;
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
/* Find probe point from its line number */
|
||||
|
@ -1484,6 +1484,8 @@ static int find_probes(int fd, struct probe_finder *pf)
|
|||
pf->lno = pp->line;
|
||||
ret = find_probe_point_by_line(pf);
|
||||
}
|
||||
if (ret != DWARF_CB_OK)
|
||||
break;
|
||||
}
|
||||
off = noff;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue