From: "Steven Rostedt (Google)" <rostedt@goodmis.org>
The iterators had three issues.
1) It used handle->max_cpu instead of handle->cpus
max_cpu is the max CPU number that was traced. But if a CPU had no data,
it was not included in the handle->cpu_data[] array, which is the
size of handle->cpus. The loop over the cpu_data[] array in the iterators
stopped at max_cpu and not cpus meaning it could overflow if one of the
CPUs had no tracing data.
2) There's no reason to free the records at the end of the iterator.
Not sure why that was done, but it was likely due to another bug that
was fixed. That freeing just fixed a symptom and not the issue.
Remove the freeing.
3) The next record for each of the CPUs was cached in a records[] array,
and when the next record to use was found, it would use that record
from the records[] array. The issue is if the callback called
tracecmd_read_data() on any of those records, it would invalidate the
one returned by "peek". Since the iterator does not know what the
callback might have done, it would have to refresh all the cached
records after each call to the callback() function.
Instead, just save the timestamps of the records for each CPU, and pick
the CPU with the next timestamp. Do the tracecmd_peek_data() on that
CPU and make sure it still matches the given timestamp. If it does not,
then try again.
Steven Rostedt (Google) (3):
libtracecmd: Use cpu_data[cpu]->cpus and not ->max_cpu
libtracecmd: Do not free records at end of iterator
libtracecmd: Just save timestamps and not the records in iterators
lib/trace-cmd/trace-input.c | 133 ++++++++++++------------------------
1 file changed, 45 insertions(+), 88 deletions(-)
From: "Steven Rostedt (Google)" <rostedt@goodmis.org> The iterators had three issues. 1) It used handle->max_cpu instead of handle->cpus max_cpu is the max CPU number that was traced. But if a CPU had no data, it was not included in the handle->cpu_data[] array, which is the size of handle->cpus. The loop over the cpu_data[] array in the iterators stopped at max_cpu and not cpus meaning it could overflow if one of the CPUs had no tracing data. 2) There's no reason to free the records at the end of the iterator. Not sure why that was done, but it was likely due to another bug that was fixed. That freeing just fixed a symptom and not the issue. Remove the freeing. 3) The next record for each of the CPUs was cached in a records[] array, and when the next record to use was found, it would use that record from the records[] array. The issue is if the callback called tracecmd_read_data() on any of those records, it would invalidate the one returned by "peek". Since the iterator does not know what the callback might have done, it would have to refresh all the cached records after each call to the callback() function. Instead, just save the timestamps of the records for each CPU, and pick the CPU with the next timestamp. Do the tracecmd_peek_data() on that CPU and make sure it still matches the given timestamp. If it does not, then try again. Steven Rostedt (Google) (3): libtracecmd: Use cpu_data[cpu]->cpus and not ->max_cpu libtracecmd: Do not free records at end of iterator libtracecmd: Just save timestamps and not the records in iterators lib/trace-cmd/trace-input.c | 133 ++++++++++++------------------------ 1 file changed, 45 insertions(+), 88 deletions(-)