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