From 34a0b300cd8a0cd8d48a042128ba99ad8a8b4d1d Mon Sep 17 00:00:00 2001 From: bingo2008 <5493992+bingo2008@user.noreply.gitee.com> Date: Thu, 28 Nov 2019 20:19:57 +0800 Subject: [PATCH] Package init --- ARM64.patch | 13 + TRACE_EVENT_FL_TRACEPOINT_flag.patch | 743 +++++++++++++++++++++++++++ big_endian_nr_pages.patch | 26 + crash-trace-command-2.0.tar.gz | Bin 0 -> 17472 bytes crash-trace-command.spec | 46 ++ ftrace_event_call_rh_data.patch | 43 ++ initialize_trace_dat.patch | 11 + linux_3.10_support.patch | 152 ++++++ linux_4.2_support.patch | 265 ++++++++++ ppc64_ring_buffer_read.patch | 13 + ppc64le.patch | 13 + replace_obsolete_init_and_fini.patch | 31 ++ sigsegv_on_calloc_failure.patch | 10 + trace_compiler_warnings.patch | 46 ++ 14 files changed, 1412 insertions(+) create mode 100644 ARM64.patch create mode 100644 TRACE_EVENT_FL_TRACEPOINT_flag.patch create mode 100644 big_endian_nr_pages.patch create mode 100644 crash-trace-command-2.0.tar.gz create mode 100644 crash-trace-command.spec create mode 100644 ftrace_event_call_rh_data.patch create mode 100644 initialize_trace_dat.patch create mode 100644 linux_3.10_support.patch create mode 100644 linux_4.2_support.patch create mode 100644 ppc64_ring_buffer_read.patch create mode 100644 ppc64le.patch create mode 100644 replace_obsolete_init_and_fini.patch create mode 100644 sigsegv_on_calloc_failure.patch create mode 100644 trace_compiler_warnings.patch diff --git a/ARM64.patch b/ARM64.patch new file mode 100644 index 0000000..ff7abd0 --- /dev/null +++ b/ARM64.patch @@ -0,0 +1,13 @@ +--- crash-trace-command-2.0/Makefile.orig ++++ crash-trace-command-2.0/Makefile +@@ -22,6 +22,10 @@ ifeq ($(shell arch), s390) + TARGET=S390 + TARGET_CFLAGS= + endif ++ifeq ($(shell arch), aarch64) ++ TARGET=ARM64 ++ TARGET_CFLAGS= ++endif + + INCDIR=/usr/include/crash + diff --git a/TRACE_EVENT_FL_TRACEPOINT_flag.patch b/TRACE_EVENT_FL_TRACEPOINT_flag.patch new file mode 100644 index 0000000..530f1ed --- /dev/null +++ b/TRACE_EVENT_FL_TRACEPOINT_flag.patch @@ -0,0 +1,743 @@ +--- crash-trace-command-2.0/trace.c.orig ++++ crash-trace-command-2.0/trace.c +@@ -38,6 +38,10 @@ static int trace_buffer_available; + * max_buffer is supported + */ + static int max_buffer_available; ++/* ++ * multiple trace instances are supported ++ */ ++static int multiple_instances_available; + + #define koffset(struct, member) struct##_##member##_offset + +@@ -78,6 +82,8 @@ static int koffset(ftrace_event_field, o + static int koffset(ftrace_event_field, size); + static int koffset(ftrace_event_field, is_signed); + ++static int koffset(trace_array, name); ++ + static int koffset(POINTER_SYM, POINTER) = 0; + + struct ring_buffer_per_cpu { +@@ -101,16 +107,25 @@ struct ring_buffer_per_cpu { + }; + + static ulong global_trace; +-static ulong global_trace_buffer; +-static ulong global_max_buffer; +-static ulong global_ring_buffer; +-static unsigned global_pages; +-static struct ring_buffer_per_cpu *global_buffers; +- + static ulong max_tr_trace; +-static ulong max_tr_ring_buffer; +-static unsigned max_tr_pages; +-static struct ring_buffer_per_cpu *max_tr_buffers; ++ ++struct trace_instance { ++ char name[NAME_MAX + 1]; ++ ulong trace_buffer; ++ ulong max_buffer; ++ ulong ring_buffer; ++ unsigned pages; ++ struct ring_buffer_per_cpu *buffers; ++ ++ ulong max_tr_ring_buffer; ++ unsigned max_tr_pages; ++ struct ring_buffer_per_cpu *max_tr_buffers; ++}; ++ ++static ulong ftrace_trace_arrays; ++static struct trace_instance global_trace_instance; ++static struct trace_instance *trace_instances = NULL; ++static int instance_count; + + static ulong ftrace_events; + static ulong current_trace; +@@ -229,6 +244,9 @@ static int init_offsets(void) + init_offset(ftrace_event_field, size); + init_offset(ftrace_event_field, is_signed); + ++ if (MEMBER_EXISTS("trace_array", "name")) ++ init_offset(trace_array, name); ++ + return 0; + #undef init_offset + } +@@ -435,61 +453,140 @@ out_fail: + return -1; + } + +-static int ftrace_int_global_trace(void) ++static int ftrace_init_trace(struct trace_instance *ti, ulong instance_addr) + { + if (trace_buffer_available) { +- global_trace_buffer = global_trace + koffset(trace_array, trace_buffer); +- read_value(global_ring_buffer, global_trace_buffer, trace_buffer, buffer); ++ ti->trace_buffer = instance_addr + ++ koffset(trace_array, trace_buffer); ++ read_value(ti->ring_buffer, ti->trace_buffer, ++ trace_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); ++ } + } else { +- read_value(global_ring_buffer, global_trace, trace_array, buffer); +- read_value(global_pages, global_ring_buffer, ring_buffer, pages); ++ read_value(ti->ring_buffer, instance_addr, trace_array, buffer); ++ read_value(ti->pages, ti->ring_buffer, ring_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); + } + +- global_buffers = calloc(sizeof(*global_buffers), nr_cpu_ids); +- if (global_buffers == NULL) ++ 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, ++ ti->pages) < 0) ++ goto out_fail; ++ ++ if (!ti->max_tr_ring_buffer) ++ return 0; ++ ++ ti->max_tr_buffers = calloc(sizeof(*ti->max_tr_buffers), nr_cpu_ids); ++ if (ti->max_tr_buffers == NULL) + goto out_fail; + +- if (ftrace_init_buffers(global_buffers, global_ring_buffer, +- global_pages) < 0) ++ if (ftrace_init_buffers(ti->max_tr_buffers, ti->max_tr_ring_buffer, ++ ti->max_tr_pages) < 0) + goto out_fail; + + return 0; + + out_fail: +- free(global_buffers); ++ free(ti->max_tr_buffers); ++ free(ti->buffers); + return -1; + } + +-static int ftrace_int_max_tr_trace(void) ++static void ftrace_destroy_all_instance_buffers() + { +- if (trace_buffer_available) { +- if (!max_buffer_available) +- return 0; ++ int i; + +- global_max_buffer = global_trace + koffset(trace_array, max_buffer); +- read_value(max_tr_ring_buffer, global_max_buffer, trace_buffer, buffer); +- } else { +- read_value(max_tr_ring_buffer, max_tr_trace, trace_array, buffer); ++ for (i = 0; i < instance_count; i++) ++ { ++ struct trace_instance *ti = &trace_instances[i]; + +- if (!max_tr_ring_buffer) +- return 0; ++ if (ti->max_tr_ring_buffer) { ++ ftrace_destroy_buffers(ti->max_tr_buffers); ++ free(ti->max_tr_buffers); ++ } + +- read_value(max_tr_pages, max_tr_ring_buffer, ring_buffer, pages); ++ ftrace_destroy_buffers(ti->buffers); ++ free(ti->buffers); + } ++} + +- max_tr_buffers = calloc(sizeof(*max_tr_buffers), nr_cpu_ids); +- if (max_tr_buffers == NULL) +- goto out_fail; ++static void ftrace_destroy_instances() ++{ ++ ftrace_destroy_all_instance_buffers(); ++ free(trace_instances); ++} + +- if (ftrace_init_buffers(max_tr_buffers, max_tr_ring_buffer, +- max_tr_pages) < 0) +- goto out_fail; ++static int ftrace_init_instances() ++{ ++ int i; ++ struct trace_instance *ti; ++ struct list_data list_data; ++ struct list_data *ld = &list_data; ++ ++ if (!multiple_instances_available) ++ return 0; ++ ++ BZERO(ld, sizeof(struct list_data)); ++ ld->start = ftrace_trace_arrays; ++ ld->end = global_trace; ++ ld->flags = LIST_ALLOCATE; ++ instance_count = do_list(ld); ++ ++ /* The do_list count includes the list_head, which is not a ++ * proper instance */ ++ instance_count--; ++ if (instance_count <= 0) ++ return 0; ++ ++ trace_instances = calloc(sizeof(struct trace_instance), instance_count); ++ ++ /* We start i at 1 to skip over the list_head and continue to the last ++ * instance, which lies at index instance_count */ ++ for (i = 1; i <= instance_count; i++) ++ { ++ ulong instance_ptr; ++ ulong name_addr; ++ int ret; ++ ++ ti = &trace_instances[i-1]; ++ instance_ptr = ld->list_ptr[i]; ++ read_value(name_addr, instance_ptr, trace_array, name); ++ if (!name_addr) ++ { ++ console("Instance name is NULL\n"); ++ } ++ else if (!read_string(name_addr, ti->name, sizeof(ti->name))) ++ { ++ console("Failed to read instance name at address %p\n", (void*)name_addr); ++ goto out_fail; ++ } ++ ++ ret = ftrace_init_trace(ti, instance_ptr); ++ if (ret < 0) ++ goto out_fail; ++ } ++ FREEBUF(ld->list_ptr); + + return 0; + + out_fail: +- free(max_tr_buffers); +- max_tr_ring_buffer = 0; ++ /* We've already freed the current instance's trace buffer info, so ++ * we'll clear that out to avoid double freeing in ++ * ftrace_destroy_instances() */ ++ BZERO(ti, sizeof(struct trace_instance)); ++ ftrace_destroy_instances(); ++ + return -1; + } + +@@ -504,7 +601,7 @@ static int ftrace_init_current_tracer(vo + } else { + read_value(addr, current_trace, POINTER_SYM, POINTER); + } +- ++ + read_value(addr, addr, tracer, name); + read_string(addr, tmp, 128); + +@@ -524,9 +621,11 @@ static int ftrace_init(void) + struct syment *sym_max_tr_trace; + struct syment *sym_ftrace_events; + struct syment *sym_current_trace; ++ struct syment *sym_ftrace_trace_arrays; + + sym_global_trace = symbol_search("global_trace"); + sym_ftrace_events = symbol_search("ftrace_events"); ++ sym_ftrace_trace_arrays = symbol_search("ftrace_trace_arrays"); + + if (sym_global_trace == NULL || sym_ftrace_events == NULL) + return -1; +@@ -534,6 +633,13 @@ static int ftrace_init(void) + global_trace = sym_global_trace->value; + ftrace_events = sym_ftrace_events->value; + ++ if (sym_ftrace_trace_arrays) ++ { ++ multiple_instances_available = 1; ++ ftrace_trace_arrays = sym_ftrace_trace_arrays->value; ++ } ++ ++ + if (MEMBER_EXISTS("trace_array", "current_trace")) { + encapsulated_current_trace = 1; + } else { +@@ -564,28 +670,31 @@ static int ftrace_init(void) + return -1; + print_offsets(); + +- if (ftrace_int_global_trace() < 0) ++ if (ftrace_init_trace(&global_trace_instance, global_trace) < 0) + goto out_0; + +- ftrace_int_max_tr_trace(); ++ if (ftrace_init_instances() < 0) ++ goto out_1; + + if (ftrace_init_event_types() < 0) +- goto out_1; ++ goto out_2; + + if (ftrace_init_current_tracer() < 0) +- goto out_2; ++ goto out_3; + + return 0; + +-out_2: ++out_3: + ftrace_destroy_event_types(); ++out_2: ++ ftrace_destroy_instances(); + out_1: +- if (max_tr_ring_buffer) { +- ftrace_destroy_buffers(max_tr_buffers); +- free(max_tr_buffers); ++ if (global_trace_instance.max_tr_ring_buffer) { ++ ftrace_destroy_buffers(global_trace_instance.max_tr_buffers); ++ free(global_trace_instance.max_tr_buffers); + } +- ftrace_destroy_buffers(global_buffers); +- free(global_buffers); ++ ftrace_destroy_buffers(global_trace_instance.buffers); ++ free(global_trace_instance.buffers); + out_0: + return -1; + } +@@ -595,13 +704,15 @@ static void ftrace_destroy(void) + free(current_tracer_name); + ftrace_destroy_event_types(); + +- if (max_tr_ring_buffer) { +- ftrace_destroy_buffers(max_tr_buffers); +- free(max_tr_buffers); ++ ftrace_destroy_instances(); ++ ++ if (global_trace_instance.max_tr_ring_buffer) { ++ ftrace_destroy_buffers(global_trace_instance.max_tr_buffers); ++ free(global_trace_instance.max_tr_buffers); + } + +- ftrace_destroy_buffers(global_buffers); +- free(global_buffers); ++ ftrace_destroy_buffers(global_trace_instance.buffers); ++ free(global_trace_instance.buffers); + } + + static int ftrace_dump_page(int fd, ulong page, void *page_tmp) +@@ -652,7 +763,8 @@ static int try_mkdir(const char *pathnam + return 0; + } + +-static int ftrace_dump_buffers(const char *per_cpu_path) ++static int ftrace_dump_buffers(const char *per_cpu_path, ++ struct trace_instance *ti) + { + int i; + void *page_tmp; +@@ -664,7 +776,7 @@ static int ftrace_dump_buffers(const cha + return -1; + + for (i = 0; i < nr_cpu_ids; i++) { +- struct ring_buffer_per_cpu *cpu_buffer = &global_buffers[i]; ++ struct ring_buffer_per_cpu *cpu_buffer = &ti->buffers[i]; + + if (!cpu_buffer->kaddr) + continue; +@@ -679,7 +791,7 @@ static int ftrace_dump_buffers(const cha + if (fd < 0) + goto out_fail; + +- ftrace_dump_buffer(fd, cpu_buffer, global_pages, page_tmp); ++ ftrace_dump_buffer(fd, cpu_buffer, ti->pages, page_tmp); + close(fd); + } + +@@ -1015,8 +1127,6 @@ static void ftrace_destroy_event_types(v + free(ftrace_common_fields); + } + +-#define TRACE_EVENT_FL_TRACEPOINT 0x40 +- + static + int ftrace_get_event_type_name(ulong call, char *name, int len) + { +@@ -1024,34 +1134,35 @@ int ftrace_get_event_type_name(ulong cal + static int name_offset; + static int flags_offset; + static int tp_name_offset; +- uint flags; ++ static long tracepoint_flag; + ++ uint flags; + ulong name_addr; + + if (inited) + goto work; + +- inited = 1; +- name_offset = MAX(MEMBER_OFFSET("ftrace_event_call", "name"), +- MEMBER_OFFSET("trace_event_call", "name")); +- if (name_offset >= 0) +- goto work; +- +- name_offset = MAX(ANON_MEMBER_OFFSET("ftrace_event_call", "name"), +- ANON_MEMBER_OFFSET("trace_event_call", "name")); +- if (name_offset < 0) +- return -1; ++ name_offset = MAX(MEMBER_OFFSET("ftrace_event_call", "tp"), ++ MEMBER_OFFSET("trace_event_call", "tp")); ++ if (name_offset >= 0) { ++ flags_offset = MAX(MEMBER_OFFSET("ftrace_event_call", "flags"), ++ MEMBER_OFFSET("trace_event_call", "flags")); ++ if (flags_offset < 0) ++ return -1; + +- flags_offset = MAX(MEMBER_OFFSET("ftrace_event_call", "flags"), +- MEMBER_OFFSET("trace_event_call", "flags")); +- if (flags_offset < 0) +- return -1; ++ tp_name_offset = MEMBER_OFFSET("tracepoint", "name"); ++ if (tp_name_offset < 0) ++ return -1; + +- tp_name_offset = MEMBER_OFFSET("tracepoint", "name"); +- if (tp_name_offset < 0) +- return -1; ++ if (!enumerator_value("TRACE_EVENT_FL_TRACEPOINT", &tracepoint_flag)) ++ return -1; + +- inited = 2; ++ inited = 2; ++ } else { ++ name_offset = MAX(MEMBER_OFFSET("ftrace_event_call", "name"), ++ MEMBER_OFFSET("trace_event_call", "name")); ++ inited = 1; ++ } + + work: + if (name_offset < 0) +@@ -1067,7 +1178,7 @@ work: + RETURN_ON_ERROR)) + return -1; + +- if (flags & TRACE_EVENT_FL_TRACEPOINT) { ++ if (flags & (uint)tracepoint_flag) { + if (!readmem(name_addr + tp_name_offset, KVADDR, + &name_addr, sizeof(name_addr), + "read tracepoint name", RETURN_ON_ERROR)) +@@ -1476,26 +1587,72 @@ static int dump_kallsyms(const char *dum + + static int trace_cmd_data_output(int fd); + ++#define FTRACE_DUMP_SYMBOLS (1 << 0) ++#define FTRACE_DUMP_META_DATA (1 << 1) ++ ++static int populate_ftrace_dir_tree(struct trace_instance *ti, ++ char *root, uint flags) ++{ ++ char path[PATH_MAX]; ++ int ret; ++ ++ ret = mkdir(root, 0755); ++ if (ret < 0) { ++ if (errno == EEXIST) ++ error(INFO, "mkdir: %s exists\n", root); ++ return FALSE; ++ } ++ ++ snprintf(path, sizeof(path), "%s/per_cpu", root); ++ if (try_mkdir(path, 0755) < 0) ++ return FALSE; ++ ++ if (ftrace_dump_buffers(path, ti) < 0) ++ return FALSE; ++ ++ if (flags & FTRACE_DUMP_META_DATA) { ++ /* Dump event types */ ++ snprintf(path, sizeof(path), "%s/events", root); ++ if (try_mkdir(path, 0755) < 0) ++ return FALSE; ++ ++ if (ftrace_dump_event_types(path) < 0) ++ return FALSE; ++ ++ /* Dump pids with corresponding cmdlines */ ++ if (dump_saved_cmdlines(root) < 0) ++ return FALSE; ++ } ++ ++ if (flags & FTRACE_DUMP_SYMBOLS) { ++ /* Dump all symbols of the kernel */ ++ dump_kallsyms(root); ++ } ++ ++ return TRUE; ++} ++ + static void ftrace_dump(int argc, char *argv[]) + { + int c; +- int dump_meta_data = 0; +- int dump_symbols = 0; ++ int i; ++ uint flags = 0; + char *dump_tracing_dir; +- char path[PATH_MAX]; +- int ret; ++ char instance_path[PATH_MAX]; + + while ((c = getopt(argc, argv, "smt")) != EOF) { + switch(c) + { + case 's': +- dump_symbols = 1; ++ flags |= FTRACE_DUMP_SYMBOLS; + break; + case 'm': +- dump_meta_data = 1; ++ flags |= FTRACE_DUMP_META_DATA; + break; + case 't': +- if (dump_symbols || dump_meta_data || argc - optind > 1) ++ if (flags & FTRACE_DUMP_SYMBOLS || ++ flags & FTRACE_DUMP_META_DATA || ++ argc - optind > 1) + cmd_usage(pc->curcmd, SYNOPSIS); + else { + char *trace_dat = "trace.dat"; +@@ -1526,38 +1683,34 @@ static void ftrace_dump(int argc, char * + return; + } + +- ret = mkdir(dump_tracing_dir, 0755); +- if (ret < 0) { +- if (errno == EEXIST) +- error(INFO, "mkdir: %s exists\n", dump_tracing_dir); ++ if (!populate_ftrace_dir_tree(&global_trace_instance, dump_tracing_dir, flags)) + return; +- } + +- snprintf(path, sizeof(path), "%s/per_cpu", dump_tracing_dir); +- if (try_mkdir(path, 0755) < 0) ++ if (!multiple_instances_available || instance_count == 0) + return; + +- if (ftrace_dump_buffers(path) < 0) ++ /* Create an instances directory, and dump instance data in there */ ++ snprintf(instance_path, sizeof(instance_path), ++ "%s/instances", dump_tracing_dir); ++ if (try_mkdir(instance_path, 0755) < 0) + return; + +- if (dump_meta_data) { +- /* Dump event types */ +- snprintf(path, sizeof(path), "%s/events", dump_tracing_dir); +- if (try_mkdir(path, 0755) < 0) +- return; ++ /* Don't care about the flags anymore */ ++ flags = 0; + +- if (ftrace_dump_event_types(path) < 0) +- return; ++ for (i = 0; i < instance_count; i++) ++ { ++ struct trace_instance *ti = &trace_instances[i]; ++ ++ snprintf(instance_path, sizeof(instance_path), ++ "%s/instances/%s", dump_tracing_dir, ++ ti->name); + +- /* Dump pids with corresponding cmdlines */ +- if (dump_saved_cmdlines(dump_tracing_dir) < 0) +- return; ++ if (populate_ftrace_dir_tree(ti, instance_path, flags) < 0) ++ break; + } + +- if (dump_symbols) { +- /* Dump all symbols of the kernel */ +- dump_kallsyms(dump_tracing_dir); +- } ++ return; + } + + static void ftrace_show(int argc, char *argv[]) +@@ -2161,26 +2314,69 @@ static int save_ftrace_cmdlines(int fd) + return tmp_file_flush(fd); + } + +-static int save_res_data(int fd, int nr_cpu_buffers) ++/* From trace-cmd.h */ ++enum { ++ TRACECMD_OPTION_DONE, /* 0 */ ++ TRACECMD_OPTION_DATE, /* 1 */ ++ TRACECMD_OPTION_CPUSTAT, /* 2 */ ++ TRACECMD_OPTION_BUFFER, /* 3 */ ++ TRACECMD_OPTION_TRACECLOCK, /* 4 */ ++ TRACECMD_OPTION_UNAME, /* 5 */ ++ TRACECMD_OPTION_HOOK, /* 6 */ ++}; ++ ++static int write_options(int fd, unsigned long long *buffer_offsets) + { +- unsigned short option = 0; ++ int i; ++ unsigned short option; + +- if (write_and_check(fd, &nr_cpu_buffers, 4)) +- return -1; ++ if (!multiple_instances_available) ++ return 0; + + if (write_and_check(fd, "options ", 10)) + return -1; + ++ option = TRACECMD_OPTION_BUFFER; ++ for (i = 0; i < instance_count; i++) ++ { ++ char *name = trace_instances[i].name; ++ size_t name_size = strlen(name) + 1; /* Name length + '\0' */ ++ unsigned long long option_size = 8 + name_size; ++ unsigned long long offset; ++ ++ offset = buffer_offsets ? buffer_offsets[i] : 0; ++ if (write_and_check(fd, &option, 2)) ++ return -1; ++ if (write_and_check(fd, &option_size, 4)) ++ return -1; ++ if (write_and_check(fd, &offset, 8)) ++ return -1; ++ if (write_and_check(fd, name, name_size)) ++ return -1; ++ } ++ ++ option = TRACECMD_OPTION_DONE; + if (write_and_check(fd, &option, 2)) + return -1; + ++ return 0; ++} ++ ++static int save_res_data(int fd, int nr_cpu_buffers, unsigned long long *buffer_offsets) ++{ ++ if (write_and_check(fd, &nr_cpu_buffers, 4)) ++ return -1; ++ ++ if (write_options(fd, buffer_offsets)) ++ return -1; ++ + if (write_and_check(fd, "flyrecord", 10)) + return -1; + + return 0; + } + +-static int save_record_data(int fd, int nr_cpu_buffers) ++static int save_record_data(int fd, int nr_cpu_buffers, struct trace_instance *ti) + { + int i, j; + unsigned long long offset, buffer_offset; +@@ -2192,7 +2388,7 @@ static int save_record_data(int fd, int + buffer_offset = offset; + + for (i = 0; i < nr_cpu_ids; i++) { +- struct ring_buffer_per_cpu *cpu_buffer = &global_buffers[i]; ++ struct ring_buffer_per_cpu *cpu_buffer = &ti->buffers[i]; + unsigned long long buffer_size; + + if (!cpu_buffer->kaddr) +@@ -2212,7 +2408,7 @@ static int save_record_data(int fd, int + + lseek(fd, offset, SEEK_SET); + for (i = 0; i < nr_cpu_ids; i++) { +- struct ring_buffer_per_cpu *cpu_buffer = &global_buffers[i]; ++ struct ring_buffer_per_cpu *cpu_buffer = &ti->buffers[i]; + + if (!cpu_buffer->kaddr) + continue; +@@ -2231,13 +2427,13 @@ static int save_record_data(int fd, int + return 0; + } + +-static int __trace_cmd_data_output(int fd) ++static int get_nr_cpu_buffers(struct trace_instance *ti) + { + int i; + int nr_cpu_buffers = 0; + + for (i = 0; i < nr_cpu_ids; i++) { +- struct ring_buffer_per_cpu *cpu_buffer = &global_buffers[i]; ++ struct ring_buffer_per_cpu *cpu_buffer = &ti->buffers[i]; + + if (!cpu_buffer->kaddr) + continue; +@@ -2245,6 +2441,19 @@ static int __trace_cmd_data_output(int f + nr_cpu_buffers++; + } + ++ return nr_cpu_buffers; ++} ++ ++static int __trace_cmd_data_output(int fd) ++{ ++ int nr_cpu_buffers; ++ unsigned long long global_res_data_offset; ++ unsigned long long *instance_offsets; ++ ++ instance_offsets = calloc(sizeof(unsigned long long), instance_count); ++ ++ nr_cpu_buffers = get_nr_cpu_buffers(&global_trace_instance); ++ + if (save_initial_data(fd)) + return -1; + if (save_header_files(fd)) +@@ -2257,9 +2466,38 @@ static int __trace_cmd_data_output(int f + return -1; + if (save_ftrace_cmdlines(fd)) + return -1; +- if (save_res_data(fd, nr_cpu_buffers)) ++ ++ /* We don't have the instance buffer offsets yet, so we'll write in 0s ++ * for now, and fix it up after we have that information available */ ++ global_res_data_offset = lseek(fd, 0, SEEK_CUR); ++ if (save_res_data(fd, nr_cpu_buffers, NULL)) + return -1; +- if (save_record_data(fd, nr_cpu_buffers)) ++ if (save_record_data(fd, nr_cpu_buffers, &global_trace_instance)) ++ return -1; ++ ++ if (multiple_instances_available) ++ { ++ int i; ++ ++ for (i = 0; i < instance_count; i++) ++ { ++ struct trace_instance *ti = &trace_instances[i]; ++ nr_cpu_buffers = get_nr_cpu_buffers(ti); ++ ++ /* Save off the instance offset for fixup later */ ++ instance_offsets[i] = lseek(fd, 0, SEEK_CUR); ++ ++ if (write_and_check(fd, "flyrecord", 10)) ++ return -1; ++ if (save_record_data(fd, nr_cpu_buffers, ti)) ++ return -1; ++ } ++ } ++ ++ /* Fix up the global trace's options header with the instance offsets */ ++ lseek(fd, global_res_data_offset, SEEK_SET); ++ nr_cpu_buffers = get_nr_cpu_buffers(&global_trace_instance); ++ if (save_res_data(fd, nr_cpu_buffers, instance_offsets)) + return -1; + + return 0; diff --git a/big_endian_nr_pages.patch b/big_endian_nr_pages.patch new file mode 100644 index 0000000..3498fad --- /dev/null +++ b/big_endian_nr_pages.patch @@ -0,0 +1,26 @@ +--- crash-trace-command-2.0/trace.c.orig ++++ crash-trace-command-2.0/trace.c +@@ -96,7 +96,7 @@ struct ring_buffer_per_cpu { + ulong real_head_page; + + int head_page_index; +- unsigned int nr_pages; ++ unsigned long nr_pages; + ulong *pages; + + ulong *linear_pages; +@@ -430,7 +432,13 @@ static int ftrace_init_buffers(struct ri + buffer_read_value(overrun); + buffer_read_value(entries); + if (per_cpu_buffer_sizes) { +- buffer_read_value(nr_pages); ++ if (MEMBER_SIZE("ring_buffer_per_cpu", "nr_pages") == sizeof(unsigned int)) { ++ unsigned int tmp_nr_pages; ++ read_value(tmp_nr_pages, buffers[i].kaddr, ring_buffer_per_cpu, nr_pages); ++ buffers[i].nr_pages = (unsigned long) tmp_nr_pages; ++ } else { ++ buffer_read_value(nr_pages); ++ } + pages = buffers[i].nr_pages; + } else + buffers[i].nr_pages = pages; diff --git a/crash-trace-command-2.0.tar.gz b/crash-trace-command-2.0.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..8860f2031f35b5e25fa6e55142507fdd439d40b9 GIT binary patch literal 17472 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 7.2.0-2 +Requires: trace-cmd crash >= 7.2.0-2 + +Patch0001: trace_compiler_warnings.patch +Patch0002: replace_obsolete_init_and_fini.patch +Patch0003: sigsegv_on_calloc_failure.patch +Patch0004: initialize_trace_dat.patch +Patch0005: ARM64.patch +Patch0006: linux_3.10_support.patch +Patch0007: ppc64le.patch +Patch0008: linux_4.2_support.patch +Patch0009: TRACE_EVENT_FL_TRACEPOINT_flag.patch +Patch0010: big_endian_nr_pages.patch +Patch0011: ppc64_ring_buffer_read.patch +Patch0012: ftrace_event_call_rh_data.patch + +%description +This package provides a trace extension module for the crash utility, +allowing it to read ftrace data from a core dump file. + +%prep +%autosetup -n %{name}-%{version} -p1 + +%build +make + +%install +install -d %{buildroot}%{_libdir}/crash/extensions/ +cp %{_builddir}/crash-trace-command-%{version}/trace.so %{buildroot}%{_libdir}/crash/extensions/ + +%files +%defattr(-,root,root) +%{_libdir}/crash/extensions/trace.so +%doc COPYING + +%changelog +* Sat Nov 23 2019 fengbing - 2.0-15 +- Package init diff --git a/ftrace_event_call_rh_data.patch b/ftrace_event_call_rh_data.patch new file mode 100644 index 0000000..4c38597 --- /dev/null +++ b/ftrace_event_call_rh_data.patch @@ -0,0 +1,43 @@ + +Fix the extension trace.so for RHEL7.6, which moved +ftrace_event_call.data into an anonymous union, and the +previous offset has changed, so the trace.so extension +module fails to load, indicating "no commands registered: +shared object unloaded". + +--- crash-trace-command-2.0/trace.c.orig ++++ crash-trace-command-2.0/trace.c +@@ -853,8 +853,18 @@ static int syscall_get_enter_fields(ulon + inited = 1; + data_offset = MAX(MEMBER_OFFSET("ftrace_event_call", "data"), + MEMBER_OFFSET("trace_event_call", "data")); +- if (data_offset < 0) +- return -1; ++ if (data_offset < 0) { ++ /* ++ * rhel-7.6 moved the .data member into an anonymous union. ++ */ ++ if (MEMBER_EXISTS("ftrace_event_call", "rh_data") && ++ MEMBER_EXISTS("ftrace_event_data", "data")) { ++ data_offset = MEMBER_OFFSET("ftrace_event_call", "rh_data") + ++ MEMBER_OFFSET("ftrace_event_data", "data"); ++ inited = 2; ++ } else ++ return -1; ++ } + + enter_fields_offset = MEMBER_OFFSET("syscall_metadata", "enter_fields"); + if (enter_fields_offset < 0) +@@ -868,6 +878,12 @@ work: + "read ftrace_event_call data", RETURN_ON_ERROR)) + return -1; + ++ if (inited == 2) { ++ if (!readmem(metadata, KVADDR, &metadata, sizeof(metadata), ++ "read ftrace_event_call data (indirect rh_data)", RETURN_ON_ERROR)) ++ return -1; ++ } ++ + *fields = metadata + enter_fields_offset; + return 0; + } diff --git a/initialize_trace_dat.patch b/initialize_trace_dat.patch new file mode 100644 index 0000000..6b1a25b --- /dev/null +++ b/initialize_trace_dat.patch @@ -0,0 +1,11 @@ +--- crash-trace-command-2.0/trace.c.orig ++++ crash-trace-command-2.0/trace.c +@@ -1373,7 +1373,7 @@ static void ftrace_dump(int argc, char * + if (dump_symbols || dump_meta_data || argc - optind > 1) + cmd_usage(pc->curcmd, SYNOPSIS); + else { +- char *trace_dat; ++ char *trace_dat = "trace.dat"; + int fd; + + if (argc - optind == 0) diff --git a/linux_3.10_support.patch b/linux_3.10_support.patch new file mode 100644 index 0000000..d520492 --- /dev/null +++ b/linux_3.10_support.patch @@ -0,0 +1,152 @@ +--- crash-trace-command-2.0/trace.c.orig ++++ crash-trace-command-2.0/trace.c +@@ -26,9 +26,21 @@ static int nr_cpu_ids; + */ + static int lockless_ring_buffer; + static int per_cpu_buffer_sizes; ++/* ++ * global and encapsulated current_trace are both supported ++ */ ++static int encapsulated_current_trace; ++/* ++ * trace_buffer is supported ++ */ ++static int trace_buffer_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, max_buffer); ++static int koffset(trace_buffer, buffer); + static int koffset(trace_array, buffer); + static int koffset(tracer, name); + +@@ -85,6 +97,8 @@ struct ring_buffer_per_cpu { + }; + + static ulong global_trace; ++static ulong global_trace_buffer; ++static ulong global_max_buffer; + static ulong global_ring_buffer; + static unsigned global_pages; + static struct ring_buffer_per_cpu *global_buffers; +@@ -144,8 +158,16 @@ static int init_offsets(void) + } \ + } while (0) + ++ if (encapsulated_current_trace) ++ init_offset(trace_array, current_trace); + +- init_offset(trace_array, buffer); ++ if (trace_buffer_available) { ++ init_offset(trace_array, trace_buffer); ++ init_offset(trace_array, max_buffer); ++ init_offset(trace_buffer, buffer); ++ } else { ++ init_offset(trace_array, buffer); ++ } + init_offset(tracer, name); + + if (MEMBER_EXISTS("ring_buffer_per_cpu", "nr_pages")) { +@@ -400,8 +422,13 @@ out_fail: + + static int ftrace_int_global_trace(void) + { +- read_value(global_ring_buffer, global_trace, trace_array, buffer); +- read_value(global_pages, global_ring_buffer, ring_buffer, pages); ++ if (trace_buffer_available) { ++ global_trace_buffer = global_trace + koffset(trace_array, trace_buffer); ++ read_value(global_ring_buffer, global_trace_buffer, trace_buffer, buffer); ++ } else { ++ read_value(global_ring_buffer, global_trace, trace_array, buffer); ++ read_value(global_pages, global_ring_buffer, ring_buffer, pages); ++ } + + global_buffers = calloc(sizeof(*global_buffers), nr_cpu_ids); + if (global_buffers == NULL) +@@ -420,12 +447,17 @@ out_fail: + + static int ftrace_int_max_tr_trace(void) + { +- read_value(max_tr_ring_buffer, max_tr_trace, trace_array, buffer); ++ if (trace_buffer_available) { ++ global_max_buffer = global_trace + koffset(trace_array, max_buffer); ++ read_value(max_tr_ring_buffer, global_max_buffer, trace_buffer, buffer); ++ } else { ++ read_value(max_tr_ring_buffer, max_tr_trace, trace_array, buffer); + +- if (!max_tr_ring_buffer) +- return 0; ++ if (!max_tr_ring_buffer) ++ return 0; + +- read_value(max_tr_pages, max_tr_ring_buffer, ring_buffer, pages); ++ read_value(max_tr_pages, max_tr_ring_buffer, ring_buffer, pages); ++ } + + max_tr_buffers = calloc(sizeof(*max_tr_buffers), nr_cpu_ids); + if (max_tr_buffers == NULL) +@@ -449,7 +481,12 @@ static int ftrace_init_current_tracer(vo + char tmp[128]; + + /* Get current tracer name */ +- read_value(addr, current_trace, POINTER_SYM, POINTER); ++ if (encapsulated_current_trace) { ++ read_value(addr, global_trace, trace_array, current_trace); ++ } else { ++ read_value(addr, current_trace, POINTER_SYM, POINTER); ++ } ++ + read_value(addr, addr, tracer, name); + read_string(addr, tmp, 128); + +@@ -471,19 +508,33 @@ static int ftrace_init(void) + struct syment *sym_current_trace; + + sym_global_trace = symbol_search("global_trace"); +- sym_max_tr_trace = symbol_search("max_tr"); + sym_ftrace_events = symbol_search("ftrace_events"); +- sym_current_trace = symbol_search("current_trace"); + +- if (sym_global_trace == NULL || sym_max_tr_trace == NULL +- || sym_ftrace_events == NULL +- || sym_current_trace == NULL) ++ if (sym_global_trace == NULL || sym_ftrace_events == NULL) + return -1; + + global_trace = sym_global_trace->value; +- max_tr_trace = sym_max_tr_trace->value; + ftrace_events = sym_ftrace_events->value; +- current_trace = sym_current_trace->value; ++ ++ if (MEMBER_EXISTS("trace_array", "current_trace")) { ++ encapsulated_current_trace = 1; ++ } else { ++ sym_current_trace = symbol_search("current_trace"); ++ if (sym_current_trace == NULL) ++ return -1; ++ ++ current_trace = sym_current_trace->value; ++ } ++ ++ if (MEMBER_EXISTS("trace_array", "trace_buffer")) { ++ trace_buffer_available = 1; ++ } else { ++ sym_max_tr_trace = symbol_search("max_tr"); ++ if (sym_max_tr_trace == NULL) ++ return -1; ++ ++ max_tr_trace = sym_max_tr_trace->value; ++ } + + if (!try_get_symbol_data("nr_cpu_ids", sizeof(int), &nr_cpu_ids)) + nr_cpu_ids = 1; +@@ -1453,6 +1504,7 @@ static void ftrace_show(int argc, char * + if ((file = popen(trace_cmd, "r"))) { + ret = fread(buf, 1, sizeof(buf), file); + buf[ret] = 0; ++ pclose(file); + } + if (!strstr(buf, "trace-cmd version")) { + if (env_trace_cmd) diff --git a/linux_4.2_support.patch b/linux_4.2_support.patch new file mode 100644 index 0000000..487b84e --- /dev/null +++ b/linux_4.2_support.patch @@ -0,0 +1,265 @@ +--- crash-trace-command-2.0/trace.c.orig ++++ crash-trace-command-2.0/trace.c +@@ -34,6 +34,10 @@ static int encapsulated_current_trace; + * trace_buffer is supported + */ + static int trace_buffer_available; ++/* ++ * max_buffer is supported ++ */ ++static int max_buffer_available; + + #define koffset(struct, member) struct##_##member##_offset + +@@ -154,6 +158,7 @@ static int init_offsets(void) + if (koffset(struct, member) < 0) { \ + fprintf(fp, "failed to init the offset, struct:"\ + #struct ", member:" #member); \ ++ fprintf(fp, "\n"); \ + return -1; \ + } \ + } while (0) +@@ -163,8 +168,10 @@ static int init_offsets(void) + + if (trace_buffer_available) { + init_offset(trace_array, trace_buffer); +- init_offset(trace_array, max_buffer); + init_offset(trace_buffer, buffer); ++ ++ if (max_buffer_available) ++ init_offset(trace_array, max_buffer); + } else { + init_offset(trace_array, buffer); + } +@@ -176,6 +183,9 @@ static int init_offsets(void) + fprintf(fp, "per cpu buffer sizes\n"); + } + ++ 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); +@@ -205,7 +215,12 @@ static int init_offsets(void) + + init_offset(list_head, next); + +- init_offset(ftrace_event_call, list); ++ koffset(ftrace_event_call, list) = MAX(MEMBER_OFFSET("ftrace_event_call", "list"), ++ MEMBER_OFFSET("trace_event_call", "list")); ++ if (koffset(ftrace_event_call, list) < 0) { ++ fprintf(fp, "failed to init the offset, struct:[f]trace_event_call member:list)\n"); ++ return -1; \ ++ } + + init_offset(ftrace_event_field, link); + init_offset(ftrace_event_field, name); +@@ -448,6 +463,9 @@ out_fail: + static int ftrace_int_max_tr_trace(void) + { + if (trace_buffer_available) { ++ if (!max_buffer_available) ++ return 0; ++ + global_max_buffer = global_trace + koffset(trace_array, max_buffer); + read_value(max_tr_ring_buffer, global_max_buffer, trace_buffer, buffer); + } else { +@@ -528,6 +546,9 @@ static int ftrace_init(void) + + if (MEMBER_EXISTS("trace_array", "trace_buffer")) { + trace_buffer_available = 1; ++ ++ if (MEMBER_EXISTS("trace_array", "max_buffer")) ++ max_buffer_available = 1; + } else { + sym_max_tr_trace = symbol_search("max_tr"); + if (sym_max_tr_trace == NULL) +@@ -710,7 +731,8 @@ static int syscall_get_enter_fields(ulon + goto work; + + inited = 1; +- data_offset = MEMBER_OFFSET("ftrace_event_call", "data"); ++ data_offset = MAX(MEMBER_OFFSET("ftrace_event_call", "data"), ++ MEMBER_OFFSET("trace_event_call", "data")); + if (data_offset < 0) + return -1; + +@@ -742,7 +764,8 @@ static int syscall_get_exit_fields_old(u + goto work; + + inited = 1; +- data_offset = MEMBER_OFFSET("ftrace_event_call", "data"); ++ data_offset = MAX(MEMBER_OFFSET("ftrace_event_call", "data"), ++ MEMBER_OFFSET("trace_event_call", "data")); + if (data_offset < 0) + return -1; + +@@ -803,18 +826,22 @@ int ftrace_get_event_type_fields(ulong c + goto work; + + inited = 1; +- fields_offset = MEMBER_OFFSET("ftrace_event_call", "fields"); ++ fields_offset = MAX(MEMBER_OFFSET("ftrace_event_call", "fields"), ++ MEMBER_OFFSET("trace_event_call", "fields")); + +- class_offset = MEMBER_OFFSET("ftrace_event_call", "class"); ++ class_offset = MAX(MEMBER_OFFSET("ftrace_event_call", "class"), ++ MEMBER_OFFSET("trace_event_call", "class")); + if (class_offset < 0) + goto work; + + inited = 2; +- fields_offset = MEMBER_OFFSET("ftrace_event_class", "fields"); ++ fields_offset = MAX(MEMBER_OFFSET("ftrace_event_class", "fields"), ++ MEMBER_OFFSET("trace_event_class", "fields")); + if (fields_offset < 0) + return -1; + +- get_fields_offset = MEMBER_OFFSET("ftrace_event_class", "get_fields"); ++ get_fields_offset = MAX(MEMBER_OFFSET("ftrace_event_class", "get_fields"), ++ MEMBER_OFFSET("trace_event_class", "get_fields")); + if ((sp = symbol_search("syscall_get_enter_fields")) != NULL) + syscall_get_enter_fields_value = sp->value; + if ((sp = symbol_search("syscall_get_exit_fields")) != NULL) +@@ -988,19 +1015,45 @@ static void ftrace_destroy_event_types(v + free(ftrace_common_fields); + } + ++#define TRACE_EVENT_FL_TRACEPOINT 0x40 ++ + static + int ftrace_get_event_type_name(ulong call, char *name, int len) + { + static int inited; + static int name_offset; ++ static int flags_offset; ++ static int tp_name_offset; ++ uint flags; + + ulong name_addr; + +- if (!inited) { +- inited = 1; +- name_offset = MEMBER_OFFSET("ftrace_event_call", "name"); +- } ++ if (inited) ++ goto work; + ++ inited = 1; ++ name_offset = MAX(MEMBER_OFFSET("ftrace_event_call", "name"), ++ MEMBER_OFFSET("trace_event_call", "name")); ++ if (name_offset >= 0) ++ goto work; ++ ++ name_offset = MAX(ANON_MEMBER_OFFSET("ftrace_event_call", "name"), ++ ANON_MEMBER_OFFSET("trace_event_call", "name")); ++ if (name_offset < 0) ++ return -1; ++ ++ flags_offset = MAX(MEMBER_OFFSET("ftrace_event_call", "flags"), ++ MEMBER_OFFSET("trace_event_call", "flags")); ++ if (flags_offset < 0) ++ return -1; ++ ++ tp_name_offset = MEMBER_OFFSET("tracepoint", "name"); ++ if (tp_name_offset < 0) ++ return -1; ++ ++ inited = 2; ++ ++work: + if (name_offset < 0) + return -1; + +@@ -1008,6 +1061,21 @@ int ftrace_get_event_type_name(ulong cal + "read ftrace_event_call name_addr", RETURN_ON_ERROR)) + return -1; + ++ if (inited == 2) { ++ if (!readmem(call + flags_offset, KVADDR, &flags, ++ sizeof(flags), "read ftrace_event_call flags", ++ RETURN_ON_ERROR)) ++ return -1; ++ ++ if (flags & TRACE_EVENT_FL_TRACEPOINT) { ++ if (!readmem(name_addr + tp_name_offset, KVADDR, ++ &name_addr, sizeof(name_addr), ++ "read tracepoint name", RETURN_ON_ERROR)) ++ return -1; ++ } ++ ++ } ++ + if (!read_string(name_addr, name, len)) + return -1; + +@@ -1028,16 +1096,19 @@ int ftrace_get_event_type_system(ulong c + goto work; + + inited = 1; +- sys_offset = MEMBER_OFFSET("ftrace_event_call", "system"); ++ sys_offset = MAX(MEMBER_OFFSET("ftrace_event_call", "system"), ++ MEMBER_OFFSET("trace_event_call", "system")); + + if (sys_offset >= 0) + goto work; + +- class_offset = MEMBER_OFFSET("ftrace_event_call", "class"); ++ class_offset = MAX(MEMBER_OFFSET("ftrace_event_call", "class"), ++ MEMBER_OFFSET("trace_event_call", "class")); + if (class_offset < 0) + return -1; + +- sys_offset = MEMBER_OFFSET("ftrace_event_class", "system"); ++ sys_offset = MAX(MEMBER_OFFSET("ftrace_event_class", "system"), ++ MEMBER_OFFSET("trace_event_class", "system")); + inited = 2; + + work: +@@ -1109,7 +1180,8 @@ int ftrace_get_event_type_print_fmt(ulon + + if (!inited) { + inited = 1; +- fmt_offset = MEMBER_OFFSET("ftrace_event_call", "print_fmt"); ++ fmt_offset = MAX(MEMBER_OFFSET("ftrace_event_call", "print_fmt"), ++ MEMBER_OFFSET("trace_event_call", "print_fmt")); + } + + if (fmt_offset < 0) { +@@ -1132,11 +1204,13 @@ int ftrace_get_event_type_id(ulong call, + + if (!inited) { + inited = 1; +- id_offset = MEMBER_OFFSET("ftrace_event_call", "id"); ++ id_offset = MAX(MEMBER_OFFSET("ftrace_event_call", "id"), ++ MEMBER_OFFSET("trace_event_call", "id")); + + if (id_offset < 0) { + /* id = call->event.type */ +- int f1 = MEMBER_OFFSET("ftrace_event_call", "event"); ++ int f1 = MAX(MEMBER_OFFSET("ftrace_event_call", "event"), ++ MEMBER_OFFSET("trace_event_call", "event")); + int f2 = MEMBER_OFFSET("trace_event", "type"); + + if (f1 >= 0 && f2 >= 0) +@@ -1495,7 +1569,6 @@ static void ftrace_show(int argc, char * + FILE *file; + size_t ret; + size_t nitems __attribute__ ((__unused__)); +- char *unused __attribute__ ((__unused__)); + + /* check trace-cmd */ + if (env_trace_cmd) +@@ -1519,8 +1592,9 @@ static void ftrace_show(int argc, char * + } + + /* dump trace.dat to the temp file */ +- unused = mktemp(tmp); +- fd = open(tmp, O_WRONLY | O_CREAT | O_TRUNC, 0644); ++ fd = mkstemp(tmp); ++ if (fd < 0) ++ return; + if (trace_cmd_data_output(fd) < 0) + goto out; + diff --git a/ppc64_ring_buffer_read.patch b/ppc64_ring_buffer_read.patch new file mode 100644 index 0000000..84ab1c8 --- /dev/null +++ b/ppc64_ring_buffer_read.patch @@ -0,0 +1,13 @@ +--- crash-trace-command-2.0/trace.c.orig ++++ crash-trace-command-2.0/trace.c +@@ -198,7 +198,9 @@ static int init_offsets(void) + fprintf(fp, "per cpu buffer sizes\n"); + } + +- if (kernel_symbol_exists("ring_buffer_read")) ++ if (machine_type("PPC64") && kernel_symbol_exists(".ring_buffer_read")) ++ gdb_set_crash_scope(symbol_value(".ring_buffer_read"), ".ring_buffer_read"); ++ 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) diff --git a/ppc64le.patch b/ppc64le.patch new file mode 100644 index 0000000..b787e66 --- /dev/null +++ b/ppc64le.patch @@ -0,0 +1,13 @@ +--- crash-trace-command-2.0/Makefile.orig ++++ crash-trace-command-2.0/Makefile +@@ -6,6 +6,10 @@ ifeq ($(shell arch), ppc64) + TARGET=PPC64 + TARGET_CFLAGS=-m64 + endif ++ifeq ($(shell arch), ppc64le) ++ TARGET=PPC64 ++ TARGET_CFLAGS=-m64 ++endif + ifeq ($(shell arch), ia64) + TARGET=IA64 + TARGET_CFLAGS= diff --git a/replace_obsolete_init_and_fini.patch b/replace_obsolete_init_and_fini.patch new file mode 100644 index 0000000..1357429 --- /dev/null +++ b/replace_obsolete_init_and_fini.patch @@ -0,0 +1,31 @@ +--- crash-trace-command-2.0/trace.c.orig ++++ crash-trace-command-2.0/trace.c +@@ -1536,23 +1535,21 @@ static struct command_table_entry comman + + static int ftrace_initialized; + +-int _init(void) ++void __attribute__((constructor)) ++trace_init(void) + { + if (ftrace_init() < 0) +- return 0; ++ return; + + ftrace_initialized = 1; + register_extension(command_table); +- +- return 1; + } + +-int _fini(void) ++void __attribute__((destructor)) ++trace_fini(void) + { + if (ftrace_initialized) + ftrace_destroy(); +- +- return 1; + } + + #define TRACE_CMD_FILE_VERSION_STRING "6" diff --git a/sigsegv_on_calloc_failure.patch b/sigsegv_on_calloc_failure.patch new file mode 100644 index 0000000..580adac --- /dev/null +++ b/sigsegv_on_calloc_failure.patch @@ -0,0 +1,10 @@ +--- crash-trace-command-2.0/trace.c.orig ++++ crash-trace-command-2.0/trace.c +@@ -251,7 +251,6 @@ static int ftrace_init_pages(struct ring + + cpu_buffer->linear_pages = calloc(sizeof(ulong), nr_pages + 1); + if (cpu_buffer->linear_pages == NULL) { +- free(cpu_buffer->pages); + return -1; + } + diff --git a/trace_compiler_warnings.patch b/trace_compiler_warnings.patch new file mode 100644 index 0000000..904f4d0 --- /dev/null +++ b/trace_compiler_warnings.patch @@ -0,0 +1,46 @@ +--- crash-trace-command-2.0/trace.c.orig ++++ crash-trace-command-2.0/trace.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + + static int verbose = 0; + +@@ -892,7 +893,7 @@ out_fail: + + static int ftrace_init_event_type(ulong call, struct event_type *aevent_type) + { +- ulong fields_head; ++ ulong fields_head = 0; + + if (ftrace_get_event_type_fields(call, &fields_head) < 0) + return -1; +@@ -1443,6 +1444,8 @@ static void ftrace_show(int argc, char * + int fd; + FILE *file; + size_t ret; ++ size_t nitems __attribute__ ((__unused__)); ++ char *unused __attribute__ ((__unused__)); + + /* check trace-cmd */ + if (env_trace_cmd) +@@ -1465,7 +1468,7 @@ static void ftrace_show(int argc, char * + } + + /* dump trace.dat to the temp file */ +- mktemp(tmp); ++ unused = mktemp(tmp); + fd = open(tmp, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (trace_cmd_data_output(fd) < 0) + goto out; +@@ -1478,7 +1481,7 @@ static void ftrace_show(int argc, char * + ret = fread(buf, 1, sizeof(buf), file); + if (ret == 0) + break; +- fwrite(buf, 1, ret, fp); ++ nitems = fwrite(buf, 1, ret, fp); + } + pclose(file); + out: