perf tools: Fix crash in perf_hpp__reset_output_field
Jiri Olsa
reviewerPATCH 1/2 perf tools: Fix crash in perf_hpp__reset_output_field
Du Changbin reported crash [1] when calling perf_hpp__reset_output_field after unregistering field via perf_hpp__column_unregister.
This ends up in calling following list_del* sequence on the same format:
perf_hpp__column_unregister:
list_del(&format->list);
perf_hpp__reset_output_field:
list_del_init(&fmt->list);where the later list_del_init might touch already
freed formats.
Fixing this by replacing list_del with list_del_init in perf_hpp__column_unregister.
[1] http://marc.info/?l=linux-kernel&m=149059595826019&w=2
--- tools/perf/ui/hist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/ui/hist.c +1 -1
@@ -530,7 +530,7 @@ void perf_hpp_list__prepend_sort_field(struct perf_hpp_list *list,void perf_hpp__column_unregister (struct perf_hpp_fmt *format) { -list_del (&format->list); +list_del_init (&format->list); }void perf_hpp__cancel_cumulate (void )
Signature · 1 line
2.9.4
Jiri Olsa
reviewerPATCH 2/2 perf tools: Remove extra list_del_init calls in list reset
We only needs to remove the format from the currently iterated list. The other removals/inits are superfluous because we free the format in any case.
--- tools/perf/ui/hist.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
tools/perf/ui/hist.c +4 -4
@@ -614,15 +614,15 @@ void perf_hpp__reset_output_field(struct perf_hpp_list *list)/* reset output fields */ perf_hpp_list__for_each_format_safe (list, fmt, tmp) { -list_del_init (&fmt->list); -list_del_init (&fmt->sort_list); +list_del (&fmt->list); +/* Remove the fmt from next loop processing. */ +list_del (&fmt->sort_list);fmt_free (fmt); }/* reset sort keys */ perf_hpp_list__for_each_sort_list_safe (list, fmt, tmp) { -list_del_init (&fmt->list); -list_del_init (&fmt->sort_list); +list_del (&fmt->sort_list);fmt_free (fmt); } }
Signature · 1 line
2.9.4
Arnaldo Carvalho de Melo
maintainerRe: [PATCH 2/2] perf tools: Remove extra list_del_init calls in list reset
Em Thu, Jun 01, 2017 at 01:17:44PM +0200, Jiri Olsa escreveu:
Quoted 15 lines
We only needs to remove the format from the currently iterated list. The other removals/inits are superfluous because we free the format in any case.
Signed-off-by Jiri Olsa <[email protected]>--- tools/perf/ui/hist.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)tools/perf/ui/hist.c +0
-0
tools/perf/ui/hist.c void perf_hpp__reset_output_field(struct perf_hpp_list *list) · line 619
Quoted 8 lines
tools/perf/ui/hist.c +3
-2@@ -614,15 +614,15 @@ void perf_hpp__reset_output_field(struct perf_hpp_list *list)/* reset output fields */ perf_hpp_list__for_each_format_safe (list, fmt, tmp) { -list_del_init (&fmt->list); -list_del_init (&fmt->sort_list); +list_del (&fmt->list); +/* Remove the fmt from next loop processing. */ +list_del (&fmt->sort_list);
Why not just add the comment and leave it as list_del_init(), then, in fmt_free() -> fmt->free() -> hse_free() (for instance), have:
BUG_ON(!list_empty(&fmt->list)); BUG_ON(!list_empty(&fmt->sort_list));
The patch would be smaller and overall the code would be more robust?
tools/perf/ui/hist.c void perf_hpp__reset_output_field(struct perf_hpp_list *list) · line 625
Quoted 8 lines
tools/perf/ui/hist.c +1
-2fmt_free (fmt); }/* reset sort keys */ perf_hpp_list__for_each_sort_list_safe (list, fmt, tmp) { -list_del_init (&fmt->list); -list_del_init (&fmt->sort_list); +list_del (&fmt->sort_list);
Ditto, just ditch what you said you would do in the cset comment, i.e. ditch the extra "list_del_init(&fmt->list);" call, no?
- Arnaldo
Quoted 5 lines
tools/perf/ui/hist.c +0
-0fmt_free (fmt); } }Signature · 1 line
2.9.4
Re: [PATCH 2/2] perf tools: Remove extra list_del_init calls in list reset
Quoted 28 lines · Arnaldo Carvalho de Melo
Em Thu, Jun 01, 2017 at 01:17:44PM +0200, Jiri Olsa escreveu:
Quoted 15 lines
We only needs to remove the format from the currently iterated list. The other removals/inits are superfluous because we free the format in any case.
Signed-off-by Jiri Olsa <[email protected]>--- tools/perf/ui/hist.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)tools/perf/ui/hist.c +0
-0tools/perf/ui/hist.c void perf_hpp__reset_output_field(struct perf_hpp_list *list) · line 619
Quoted 8 lines
tools/perf/ui/hist.c +3
-2@@ -614,15 +614,15 @@ void perf_hpp__reset_output_field(struct perf_hpp_list *list)/* reset output fields */ perf_hpp_list__for_each_format_safe (list, fmt, tmp) { -list_del_init (&fmt->list); -list_del_init (&fmt->sort_list); +list_del (&fmt->list); +/* Remove the fmt from next loop processing. */ +list_del (&fmt->sort_list);Why not just add the comment and leave it as
list_del_init(), then, infmt_free()->fmt->free()->hse_free()(for instance), have:
Quoted 4 lines
BUG_ON(!list_empty(&fmt->list)); BUG_ON(!list_empty(&fmt->sort_list));The patch would be smaller and overall the code would be more robust?
ok, that could catch something.. will change
thanks,
jirka