085f43
From 2ed07609b2a8ed19ce3dda7a50b18373a6a8bd5c Mon Sep 17 00:00:00 2001
085f43
From: Dave Anderson <anderson@redhat.com>
085f43
Date: Mon, 25 Mar 2019 11:48:39 -0400
085f43
Subject: [PATCH 1/3] Fixes for the "trace.so" extension module: (1) The
085f43
 reader_page can be empty if it was never read, do not record     it if it is
085f43
 empty. Better yet, do not record any page that is     empty.  The struct
085f43
 buffer_page "real_end" is not available in     older kernels, so it needs to
085f43
 be tested if it exists before we     can use it. (2) In newer kernels, the
085f43
 sp->type of kernel module symbols does not     contain the symbol type
085f43
 character unless the module's debuginfo     data has been loaded into the
085f43
 crash session.  Writing a garbage     type to the kallsyms file for trace-cmd
085f43
 to read causes it to     crash, so just always write an 'm'. (3) Add the
085f43
 "trace dump -t <trace.dat>" option to the SYNOPSIS line     of the help page.
085f43
 (rostedt@goodmis.org)
085f43
085f43
---
085f43
 trace.c | 32 +++++++++++++++++++++++++++++---
085f43
 1 file changed, 29 insertions(+), 3 deletions(-)
085f43
085f43
diff --git a/trace.c b/trace.c
085f43
index ad71951e8740..c26b6c7ec475 100644
085f43
--- a/trace.c
085f43
+++ b/trace.c
085f43
@@ -43,6 +43,11 @@ static int max_buffer_available;
085f43
  */
085f43
 static int multiple_instances_available;
085f43
 
085f43
+/*
085f43
+ * buffer_page has "real_end"
085f43
+ */
085f43
+static int buffer_page_real_end_available;
085f43
+
085f43
 #define koffset(struct, member) struct##_##member##_offset
085f43
 
085f43
 static int koffset(trace_array, current_trace);
085f43
@@ -70,6 +75,7 @@ static int koffset(ring_buffer_per_cpu, entries);
085f43
 static int koffset(buffer_page, read);
085f43
 static int koffset(buffer_page, list);
085f43
 static int koffset(buffer_page, page);
085f43
+static int koffset(buffer_page, real_end);
085f43
 
085f43
 static int koffset(list_head, next);
085f43
 
085f43
@@ -229,6 +235,7 @@ static int init_offsets(void)
085f43
 	init_offset(buffer_page, read);
085f43
 	init_offset(buffer_page, list);
085f43
 	init_offset(buffer_page, page);
085f43
+	init_offset(buffer_page, real_end);
085f43
 
085f43
 	init_offset(list_head, next);
085f43
 
085f43
@@ -281,6 +288,7 @@ static void print_offsets(void)
085f43
 	print_offset(buffer_page, read);
085f43
 	print_offset(buffer_page, list);
085f43
 	print_offset(buffer_page, page);
085f43
+	print_offset(buffer_page, real_end);
085f43
 
085f43
 	print_offset(list_head, next);
085f43
 
085f43
@@ -295,6 +303,20 @@ static void print_offsets(void)
085f43
 #undef print_offset
085f43
 }
085f43
 
085f43
+static int buffer_page_has_data(ulong page)
085f43
+{
085f43
+	uint end;
085f43
+
085f43
+	if (!buffer_page_real_end_available)
085f43
+		return 1;
085f43
+
085f43
+	/* Only write pages with data in it */
085f43
+	read_value(end, page, buffer_page, real_end);
085f43
+	return end;
085f43
+out_fail:
085f43
+	return 0;
085f43
+}
085f43
+
085f43
 static int ftrace_init_pages(struct ring_buffer_per_cpu *cpu_buffer,
085f43
 		unsigned nr_pages)
085f43
 {
085f43
@@ -361,7 +383,8 @@ static int ftrace_init_pages(struct ring_buffer_per_cpu *cpu_buffer,
085f43
 
085f43
 	/* Setup linear pages */
085f43
 
085f43
-	cpu_buffer->linear_pages[count++] = cpu_buffer->reader_page;
085f43
+	if (buffer_page_has_data(cpu_buffer->reader_page))
085f43
+		cpu_buffer->linear_pages[count++] = cpu_buffer->reader_page;
085f43
 
085f43
 	if (cpu_buffer->reader_page == cpu_buffer->commit_page)
085f43
 		goto done;
085f43
@@ -647,6 +670,8 @@ static int ftrace_init(void)
085f43
 		ftrace_trace_arrays = sym_ftrace_trace_arrays->value;
085f43
 	}
085f43
 
085f43
+	if (MEMBER_EXISTS("buffer_page", "real_end"))
085f43
+		buffer_page_real_end_available = 1;
085f43
 
085f43
 	if (MEMBER_EXISTS("trace_array", "current_trace")) {
085f43
 		encapsulated_current_trace = 1;
085f43
@@ -1809,7 +1834,7 @@ static void cmd_ftrace(void)
085f43
 static char *help_ftrace[] = {
085f43
 "trace",
085f43
 "show or dump the tracing info",
085f43
-"[ <show [-c <cpulist>] [-f [no]<flagname>]> | <dump [-sm] <dest-dir>> ]",
085f43
+"[ <show [-c <cpulist>] [-f [no]<flagname>]> | <dump [-sm] <dest-dir>> ] | <dump -t <trace.dat> ]",
085f43
 "trace",
085f43
 "    shows the current tracer and other informations.",
085f43
 "",
085f43
@@ -2184,7 +2209,8 @@ static int save_proc_kallsyms(int fd)
085f43
 			if (!strncmp(sp->name, "_MODULE_", strlen("_MODULE_")))
085f43
 				continue;
085f43
 
085f43
-			tmp_fprintf("%lx %c %s\t[%s]\n", sp->value, sp->type,
085f43
+			/* Currently sp->type for modules is not trusted */
085f43
+			tmp_fprintf("%lx %c %s\t[%s]\n", sp->value, 'm',
085f43
 					sp->name, lm->mod_name);
085f43
 		}
085f43
 	}
085f43
-- 
085f43
2.17.1
085f43