From: "Steven Rostedt (Google)" <rostedt@xxxxxxxxxxx> The callbacks path can possibly be called when the next record is NULL. Do not call the callbacks in this case, as they are not expecting a NULL record, nor should they have to. Move the code that calls the callbacks in tracecmd_iterate_events() and tracecmd_iterate_events_multi() into a single helper function to alleviate fixing one and not the other. Reported-by: Ian Rogers <irogers@xxxxxxxxxx> Fixes: 3cd1b55f3 ("trace-cmd library: Add tracecmd_follow_event()") Fixes: 82ed4a937 ("trace-cmd library: Add filtering logic for iterating events") Signed-off-by: Steven Rostedt (Google) <rostedt@xxxxxxxxxxx> --- lib/trace-cmd/trace-input.c | 42 ++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/lib/trace-cmd/trace-input.c b/lib/trace-cmd/trace-input.c index d81918249871..6a8ca2e8a6b8 100644 --- a/lib/trace-cmd/trace-input.c +++ b/lib/trace-cmd/trace-input.c @@ -2648,6 +2648,29 @@ static int call_followers(struct tracecmd_input *handle, return ret; } +static int call_callbacks(struct tracecmd_input *handle, struct tep_record *record, + int next_cpu, + int (*callback)(struct tracecmd_input *handle, + struct tep_record *, + int, void *), + void *callback_data) +{ + int ret = 0; + + if (!record) + return 0; + + if (!handle->filter || + tracecmd_filter_match(handle->filter, record) == TRACECMD_FILTER_MATCH) { + if (handle->nr_followers) + ret = call_followers(handle, record, next_cpu); + if (!ret && callback) + ret = callback(handle, record, next_cpu, callback_data); + } + + return ret; +} + /** * tracecmd_iterate_events - iterate events over a given handle * @handle: The handle to iterate over @@ -2709,13 +2732,9 @@ int tracecmd_iterate_events(struct tracecmd_input *handle, record = tracecmd_read_data(handle, next_cpu); records[next_cpu] = tracecmd_peek_data(handle, next_cpu); - if (!handle->filter || - tracecmd_filter_match(handle->filter, record) == TRACECMD_FILTER_MATCH) { - if (handle->nr_followers) - ret = call_followers(handle, record, next_cpu); - if (!ret && callback) - ret = callback(handle, record, next_cpu, callback_data); - } + ret = call_callbacks(handle, record, next_cpu, + callback, callback_data); + tracecmd_free_record(record); } } while (next_cpu >= 0 && ret >= 0); @@ -2803,14 +2822,9 @@ int tracecmd_iterate_events_multi(struct tracecmd_input **handles, record = tracecmd_read_data(handle, cpu); records[next_cpu].record = tracecmd_peek_data(handle, cpu); - if (!handle->filter || - tracecmd_filter_match(handle->filter, record) == TRACECMD_FILTER_MATCH) { - if (handle->nr_followers) - ret = call_followers(handle, record, next_cpu); + ret = call_callbacks(handle, record, next_cpu, + callback, callback_data); - if (!ret && callback) - ret = callback(handle, record, next_cpu, callback_data); - } tracecmd_free_record(record); } -- 2.35.1