trace-cmd: Fix last_timestamp logic to handle multiple files

The last_timestamp logic to check the integrity of the timestamps in the
ring buffer was done globally, but would break if multiple files were being
included where the data files had different number of CPUs. That's because
the last_timestamp array was recreated for each passed in data file and the
size of the number of CPUs for each file.

Not only was the last_timestamp broken if there were different number of
CPUs, but it was also leaking memory.

Link: https://lore.kernel.org/linux-trace-devel/20210210164543.5ecd9dbd@gandalf.local.home

Fixes: 8cf601567 ("trace-cmd: Add --ts-check option to report")
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
diff --git a/tracecmd/trace-read.c b/tracecmd/trace-read.c
index 9270fa2..ce07b6b 100644
--- a/tracecmd/trace-read.c
+++ b/tracecmd/trace-read.c
@@ -52,6 +52,7 @@
 	struct tep_record	*record;
 	struct filter		*event_filters;
 	struct filter		*event_filter_out;
+	unsigned long long	*last_timestamp;
 };
 static struct list_head handle_list;
 
@@ -1193,17 +1194,16 @@
 static void read_data_info(struct list_head *handle_list, enum output_type otype,
 			   int global)
 {
-	unsigned long long *last_timestamp;
 	struct handle_list *handles;
 	struct handle_list *last_handle;
 	struct tep_record *record;
 	struct tep_record *last_record;
 	struct tep_handle *pevent;
 	struct tep_event *event;
-	int cpus;
 	int ret;
 
 	list_for_each_entry(handles, handle_list, list) {
+		int cpus;
 
 		/* Don't process instances that we added here */
 		if (tracecmd_is_buffer_instance(handles->handle))
@@ -1218,8 +1218,8 @@
 		print_handle_file(handles);
 		printf("cpus=%d\n", cpus);
 
-		last_timestamp = calloc(cpus, sizeof(*last_timestamp));
-		if (!last_timestamp)
+		handles->last_timestamp = calloc(cpus, sizeof(*handles->last_timestamp));
+		if (!handles->last_timestamp)
 			die("allocating timestamps");
 
 		/* Latency trace is just all ASCII */
@@ -1302,31 +1302,30 @@
 		}
 		if (last_record) {
 			int cpu = last_record->cpu;
-			if (cpu >= cpus)
-				die("cpu %d creater than %d\n", cpu, cpus);
+			if (cpu >= last_handle->cpus)
+				die("cpu %d creater than %d\n", cpu, last_handle->cpus);
 			if (tscheck &&
-			    last_timestamp[cpu] > last_record->ts) {
+			    last_handle->last_timestamp[cpu] > last_record->ts) {
 				errno = 0;
 				warning("WARNING: Record on cpu %d went backwards: %lld to %lld delta: -%lld\n",
-					cpu, last_timestamp[cpu],
+					cpu, last_handle->last_timestamp[cpu],
 					last_record->ts,
-					last_timestamp[cpu] - last_record->ts);
+					last_handle->last_timestamp[cpu] - last_record->ts);
 			}
-			last_timestamp[cpu] = last_record->ts;
+			last_handle->last_timestamp[cpu] = last_record->ts;
 			print_handle_file(last_handle);
 			trace_show_data(last_handle->handle, last_record);
 			free_handle_record(last_handle);
 		}
 	} while (last_record);
 
-	free(last_timestamp);
-
 	if (profile)
 		do_trace_profile();
 
 	list_for_each_entry(handles, handle_list, list) {
 		free_filters(handles->event_filters);
 		free_filters(handles->event_filter_out);
+		free(handles->last_timestamp);
 
 		show_test(handles->handle);
 	}