From 2ed07609b2a8ed19ce3dda7a50b18373a6a8bd5c Mon Sep 17 00:00:00 2001 From: Dave Anderson 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 " 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", -"[ ] [-f [no]]> | > ]", +"[ ] [-f [no]]> | > ] | ]", "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