diff --git a/SOURCES/0001-Fixes-for-the-trace.so-extension-module.patch b/SOURCES/0001-Fixes-for-the-trace.so-extension-module.patch new file mode 100644 index 0000000..c70ece7 --- /dev/null +++ b/SOURCES/0001-Fixes-for-the-trace.so-extension-module.patch @@ -0,0 +1,121 @@ +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 + diff --git a/SOURCES/0002-extensions-trace-Rename-trace_buffer-to-array_buffer.patch b/SOURCES/0002-extensions-trace-Rename-trace_buffer-to-array_buffer.patch new file mode 100644 index 0000000..047cf92 --- /dev/null +++ b/SOURCES/0002-extensions-trace-Rename-trace_buffer-to-array_buffer.patch @@ -0,0 +1,139 @@ +From c4cdbe3c18bca496dc6b4af17e2637379528ad02 Mon Sep 17 00:00:00 2001 +From: Valentin Schneider +Date: Thu, 3 Sep 2020 21:28:46 +0100 +Subject: [PATCH 2/3] extensions/trace: Rename trace_buffer to array_buffer + +This renaming is present from Linux v5.6 upwards, and was introduced by +commit: + + 1c5eb4481e01 ("tracing: Rename trace_buffer to array_buffer") + +Rename the internal references from trace_buffer to array_buffer. Backwards +compatibility with older kernels is provided by checking whether struct +trace_array has an array_buffer field - should that not be the case, the +old naming scheme is used instead. + +Signed-off-by: Valentin Schneider +--- + trace.c | 53 +++++++++++++++++++++++++++++++++++------------------ + 1 file changed, 35 insertions(+), 18 deletions(-) + +diff --git a/trace.c b/trace.c +index c26b6c7ec475..2cea5b2d650a 100644 +--- a/trace.c ++++ b/trace.c +@@ -31,9 +31,9 @@ static int per_cpu_buffer_sizes; + */ + static int encapsulated_current_trace; + /* +- * trace_buffer is supported ++ * array_buffer (trace_buffer pre v5.6) is supported + */ +-static int trace_buffer_available; ++static int array_buffer_available; + /* + * max_buffer is supported + */ +@@ -51,9 +51,9 @@ static int buffer_page_real_end_available; + #define koffset(struct, member) struct##_##member##_offset + + static int koffset(trace_array, current_trace); +-static int koffset(trace_array, trace_buffer); ++static int koffset(trace_array, array_buffer); + static int koffset(trace_array, max_buffer); +-static int koffset(trace_buffer, buffer); ++static int koffset(array_buffer, buffer); + static int koffset(trace_array, buffer); + static int koffset(tracer, name); + +@@ -117,7 +117,7 @@ static ulong max_tr_trace; + + struct trace_instance { + char name[NAME_MAX + 1]; +- ulong trace_buffer; ++ ulong array_buffer; + ulong max_buffer; + ulong ring_buffer; + unsigned pages; +@@ -174,8 +174,7 @@ static int write_and_check(int fd, void *data, size_t size) + + static int init_offsets(void) + { +-#define init_offset(struct, member) do { \ +- koffset(struct, member) = MEMBER_OFFSET(#struct, #member);\ ++#define check_offset(struct, member) do { \ + if (koffset(struct, member) < 0) { \ + fprintf(fp, "failed to init the offset, struct:"\ + #struct ", member:" #member); \ +@@ -184,12 +183,29 @@ static int init_offsets(void) + } \ + } while (0) + ++#define init_offset(struct, member) do { \ ++ koffset(struct, member) = MEMBER_OFFSET(#struct, #member); \ ++ check_offset(struct, member); \ ++ } while (0) ++ ++#define init_offset_alternative(struct, member, alt_struct, alt_member) do { \ ++ koffset(struct, member) = MEMBER_OFFSET(#alt_struct, #alt_member); \ ++ check_offset(struct, member); \ ++ } while (0) ++ + if (encapsulated_current_trace) + init_offset(trace_array, current_trace); + +- if (trace_buffer_available) { +- init_offset(trace_array, trace_buffer); +- init_offset(trace_buffer, buffer); ++ if (array_buffer_available) { ++ if (MEMBER_EXISTS("trace_array", "array_buffer")) { ++ init_offset(trace_array, array_buffer); ++ init_offset(array_buffer, buffer); ++ } else { ++ init_offset_alternative(trace_array, array_buffer, ++ trace_array, trace_buffer); ++ init_offset_alternative(array_buffer, buffer, ++ trace_buffer, buffer); ++ } + + if (max_buffer_available) + init_offset(trace_array, max_buffer); +@@ -486,17 +502,17 @@ out_fail: + + static int ftrace_init_trace(struct trace_instance *ti, ulong instance_addr) + { +- if (trace_buffer_available) { +- ti->trace_buffer = instance_addr + +- koffset(trace_array, trace_buffer); +- read_value(ti->ring_buffer, ti->trace_buffer, +- trace_buffer, buffer); ++ if (array_buffer_available) { ++ ti->array_buffer = instance_addr + ++ koffset(trace_array, array_buffer); ++ read_value(ti->ring_buffer, ti->array_buffer, ++ array_buffer, buffer); + + if (max_buffer_available) { + ti->max_buffer = instance_addr + + koffset(trace_array, max_buffer); + read_value(ti->max_tr_ring_buffer, ti->max_buffer, +- trace_buffer, buffer); ++ array_buffer, buffer); + } + } else { + read_value(ti->ring_buffer, instance_addr, trace_array, buffer); +@@ -683,8 +699,9 @@ static int ftrace_init(void) + current_trace = sym_current_trace->value; + } + +- if (MEMBER_EXISTS("trace_array", "trace_buffer")) { +- trace_buffer_available = 1; ++ if (MEMBER_EXISTS("trace_array", "array_buffer") || ++ MEMBER_EXISTS("trace_array", "trace_buffer")) { ++ array_buffer_available = 1; + + if (MEMBER_EXISTS("trace_array", "max_buffer")) + max_buffer_available = 1; +-- +2.17.1 + diff --git a/SOURCES/0003-extensions-trace-Rename-ring_buffer-to-trace_buffer.patch b/SOURCES/0003-extensions-trace-Rename-ring_buffer-to-trace_buffer.patch new file mode 100644 index 0000000..cf53dec --- /dev/null +++ b/SOURCES/0003-extensions-trace-Rename-ring_buffer-to-trace_buffer.patch @@ -0,0 +1,139 @@ +From 1d4357ba0e0e1ec8267c32855aec5fe5abbcfec8 Mon Sep 17 00:00:00 2001 +From: Valentin Schneider +Date: Thu, 3 Sep 2020 21:28:47 +0100 +Subject: [PATCH 3/3] extensions/trace: Rename ring_buffer to trace_buffer + +This renaming is present from Linux v5.6 upwards, and was introduced by +commit: + + 13292494379f ("tracing: Make struct ring_buffer less ambiguous") + +Rename the internal references from ring_buffer to trace_buffer. Backwards +compatibility with older kernels is provided by checking whether struct +trace_buffer has a buffer field of type struct ring buffer - should that +not be the case, the newer naming scheme is used instead. + +Signed-off-by: Valentin Schneider +--- + trace.c | 50 +++++++++++++++++++++++++++++--------------------- + 1 file changed, 29 insertions(+), 21 deletions(-) + +diff --git a/trace.c b/trace.c +index 2cea5b2d650a..c33907f98b00 100644 +--- a/trace.c ++++ b/trace.c +@@ -57,10 +57,10 @@ static int koffset(array_buffer, buffer); + static int koffset(trace_array, buffer); + static int koffset(tracer, name); + +-static int koffset(ring_buffer, pages); +-static int koffset(ring_buffer, flags); +-static int koffset(ring_buffer, cpus); +-static int koffset(ring_buffer, buffers); ++static int koffset(trace_buffer, pages); ++static int koffset(trace_buffer, flags); ++static int koffset(trace_buffer, cpus); ++static int koffset(trace_buffer, buffers); + + static int koffset(ring_buffer_per_cpu, cpu); + static int koffset(ring_buffer_per_cpu, pages); +@@ -119,7 +119,7 @@ struct trace_instance { + char name[NAME_MAX + 1]; + ulong array_buffer; + ulong max_buffer; +- ulong ring_buffer; ++ ulong trace_buffer; + unsigned pages; + struct ring_buffer_per_cpu *buffers; + +@@ -225,11 +225,19 @@ static int init_offsets(void) + else if (kernel_symbol_exists("ring_buffer_read")) + gdb_set_crash_scope(symbol_value("ring_buffer_read"), "ring_buffer_read"); + +- if (!per_cpu_buffer_sizes) +- init_offset(ring_buffer, pages); +- init_offset(ring_buffer, flags); +- init_offset(ring_buffer, cpus); +- init_offset(ring_buffer, buffers); ++ if (STREQ(MEMBER_TYPE_NAME("trace_buffer", "buffer"), "ring_buffer")) { ++ if (!per_cpu_buffer_sizes) ++ init_offset_alternative(trace_buffer, pages, ring_buffer, pages); ++ init_offset_alternative(trace_buffer, flags, ring_buffer, flags); ++ init_offset_alternative(trace_buffer, cpus, ring_buffer, cpus); ++ init_offset_alternative(trace_buffer, buffers, ring_buffer, buffers); ++ } else { ++ if (!per_cpu_buffer_sizes) ++ init_offset(trace_buffer, pages); ++ init_offset(trace_buffer, flags); ++ init_offset(trace_buffer, cpus); ++ init_offset(trace_buffer, buffers); ++ } + + if (MEMBER_SIZE("ring_buffer_per_cpu", "pages") == sizeof(ulong)) { + lockless_ring_buffer = 1; +@@ -287,10 +295,10 @@ static void print_offsets(void) + print_offset(trace_array, buffer); + print_offset(tracer, name); + +- print_offset(ring_buffer, pages); +- print_offset(ring_buffer, flags); +- print_offset(ring_buffer, cpus); +- print_offset(ring_buffer, buffers); ++ print_offset(trace_buffer, pages); ++ print_offset(trace_buffer, flags); ++ print_offset(trace_buffer, cpus); ++ print_offset(trace_buffer, buffers); + + print_offset(ring_buffer_per_cpu, cpu); + print_offset(ring_buffer_per_cpu, pages); +@@ -445,12 +453,12 @@ static void ftrace_destroy_buffers(struct ring_buffer_per_cpu *buffers) + } + + static int ftrace_init_buffers(struct ring_buffer_per_cpu *buffers, +- ulong ring_buffer, unsigned pages) ++ ulong trace_buffer, unsigned pages) + { + int i; + ulong buffers_array; + +- read_value(buffers_array, ring_buffer, ring_buffer, buffers); ++ read_value(buffers_array, trace_buffer, trace_buffer, buffers); + + for (i = 0; i < nr_cpu_ids; i++) { + if (!readmem(buffers_array + sizeof(ulong) * i, KVADDR, +@@ -505,7 +513,7 @@ static int ftrace_init_trace(struct trace_instance *ti, ulong instance_addr) + if (array_buffer_available) { + ti->array_buffer = instance_addr + + koffset(trace_array, array_buffer); +- read_value(ti->ring_buffer, ti->array_buffer, ++ read_value(ti->trace_buffer, ti->array_buffer, + array_buffer, buffer); + + if (max_buffer_available) { +@@ -515,19 +523,19 @@ static int ftrace_init_trace(struct trace_instance *ti, ulong instance_addr) + array_buffer, buffer); + } + } else { +- read_value(ti->ring_buffer, instance_addr, trace_array, buffer); +- read_value(ti->pages, ti->ring_buffer, ring_buffer, pages); ++ read_value(ti->trace_buffer, instance_addr, trace_array, buffer); ++ read_value(ti->pages, ti->trace_buffer, trace_buffer, pages); + + read_value(ti->max_tr_ring_buffer, max_tr_trace, trace_array, buffer); + if (ti->max_tr_ring_buffer) +- read_value(ti->max_tr_pages, ti->max_tr_ring_buffer, ring_buffer, pages); ++ read_value(ti->max_tr_pages, ti->max_tr_ring_buffer, trace_buffer, pages); + } + + ti->buffers = calloc(sizeof(*ti->buffers), nr_cpu_ids); + if (ti->buffers == NULL) + goto out_fail; + +- if (ftrace_init_buffers(ti->buffers, ti->ring_buffer, ++ if (ftrace_init_buffers(ti->buffers, ti->trace_buffer, + ti->pages) < 0) + goto out_fail; + +-- +2.17.1 + diff --git a/SPECS/crash-trace-command.spec b/SPECS/crash-trace-command.spec index ea53a24..f476ff9 100644 --- a/SPECS/crash-trace-command.spec +++ b/SPECS/crash-trace-command.spec @@ -4,7 +4,7 @@ Summary: Trace extension module for the crash utility Name: crash-trace-command Version: 2.0 -Release: 17%{?dist} +Release: 18%{?dist} License: GPLv2 Group: Development/Debuggers Source: https://github.com/crash-utility/crash-extensions/blob/master/%{name}-%{version}.tar.gz @@ -31,6 +31,9 @@ Patch9: big_endian_nr_pages.patch Patch10: ppc64_ring_buffer_read.patch Patch11: rhel8_build.patch Patch12: ftrace_event_call_rh_data.patch +Patch13: 0001-Fixes-for-the-trace.so-extension-module.patch +Patch14: 0002-extensions-trace-Rename-trace_buffer-to-array_buffer.patch +Patch15: 0003-extensions-trace-Rename-ring_buffer-to-trace_buffer.patch %description Command for reading ftrace data from a dumpfile. @@ -50,6 +53,9 @@ Command for reading ftrace data from a dumpfile. %patch10 -p1 -b ppc64_ring_buffer_read.patch %patch11 -p1 -b rhel8_build.patch %patch12 -p1 -b ftrace_event_call_rh_data.patch +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 %build make @@ -67,6 +73,11 @@ rm -rf %{buildroot} %doc COPYING %changelog +* Mon Feb 08 2021 Lianbo Jiang - 2.0-18 +- Rename trace_buffer to array_buffer +- Rename ring_buffer to trace_buffer + Resolves: rhbz#1925907 + * Mon Jul 27 2020 Bhupesh Sharma - 2.0-17 - Chnage Source/URL to point to the latest github location Resolves: rhbz#1851746