From 0ee936eb74a75e503c92f9306ca81efca5cb9380 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: May 20 2020 11:29:46 +0000 Subject: import crash-7.2.3-11.el7 --- diff --git a/SOURCES/github_f701ecad_a812e59a_timer_rhel7.6.patch b/SOURCES/github_f701ecad_a812e59a_timer_rhel7.6.patch new file mode 100644 index 0000000..2d2f2e6 --- /dev/null +++ b/SOURCES/github_f701ecad_a812e59a_timer_rhel7.6.patch @@ -0,0 +1,272 @@ +commit f701ecad0f4b8d54b80455774b3ce4e328725a1b +Author: Dave Anderson +Date: Wed Nov 7 12:02:51 2018 -0500 + + Implemented the functionality for a new MEMBER_TYPE_NAME() macro, + which will return a pointer to the type name string of a structure + member. It is being put in place for the support of Linux 4.20 + radix tree to xarray replacements, where structure member types may + be changed from radix_tree_root structures to xarray structures. + (anderson@redhat.com) + +diff --git a/defs.h b/defs.h +index bea70c5899ef..e8ade5778dd1 100644 +--- a/defs.h ++++ b/defs.h +@@ -2232,6 +2232,7 @@ struct array_table { + #define ANON_MEMBER_OFFSET_REQUEST ((struct datatype_member *)(-2)) + #define MEMBER_TYPE_REQUEST ((struct datatype_member *)(-3)) + #define STRUCT_SIZE_REQUEST ((struct datatype_member *)(-4)) ++#define MEMBER_TYPE_NAME_REQUEST ((struct datatype_member *)(-5)) + + #define STRUCT_SIZE(X) datatype_info((X), NULL, STRUCT_SIZE_REQUEST) + #define UNION_SIZE(X) datatype_info((X), NULL, STRUCT_SIZE_REQUEST) +@@ -2241,6 +2242,7 @@ struct array_table { + #define MEMBER_EXISTS(X,Y) (datatype_info((X), (Y), NULL) >= 0) + #define MEMBER_SIZE(X,Y) datatype_info((X), (Y), MEMBER_SIZE_REQUEST) + #define MEMBER_TYPE(X,Y) datatype_info((X), (Y), MEMBER_TYPE_REQUEST) ++#define MEMBER_TYPE_NAME(X,Y) ((char *)datatype_info((X), (Y), MEMBER_TYPE_NAME_REQUEST)) + #define ANON_MEMBER_OFFSET(X,Y) datatype_info((X), (Y), ANON_MEMBER_OFFSET_REQUEST) + + /* +@@ -4546,6 +4548,10 @@ struct gnu_request { + struct objfile *obj; + } global_iterator; + struct load_module *lm; ++ char *member_main_type_name; ++ char *member_main_type_tag_name; ++ char *member_target_type_name; ++ char *member_target_type_tag_name; + }; + + /* +diff --git a/gdb-7.6.patch b/gdb-7.6.patch +index ec63c0df82b9..87447fa44094 100644 +--- a/gdb-7.6.patch ++++ b/gdb-7.6.patch +@@ -2407,3 +2407,28 @@ diff -up gdb-7.6/opcodes/configure.orig gdb-7.6/opcodes/configure + #include + #include + #include ++--- gdb-7.6/gdb/symtab.c.orig +++++ gdb-7.6/gdb/symtab.c ++@@ -5500,7 +5500,7 @@ get_member_data(struct gnu_request *req, ++ register short i; ++ struct field *nextfield; ++ short nfields; ++- struct type *typedef_type; +++ struct type *typedef_type, *target_type; ++ ++ req->member_offset = -1; ++ ++@@ -5523,6 +5523,13 @@ get_member_data(struct gnu_request *req, ++ req->member_offset = offset + nextfield->loc.bitpos; ++ req->member_length = TYPE_LENGTH(nextfield->type); ++ req->member_typecode = TYPE_CODE(nextfield->type); +++ req->member_main_type_name = (char *)TYPE_NAME(nextfield->type); +++ req->member_main_type_tag_name = (char *)TYPE_TAG_NAME(nextfield->type); +++ target_type = TYPE_TARGET_TYPE(nextfield->type); +++ if (target_type) { +++ req->member_target_type_name = (char *)TYPE_NAME(target_type); +++ req->member_target_type_tag_name = (char *)TYPE_TAG_NAME(target_type); +++ } ++ if ((req->member_typecode == TYPE_CODE_TYPEDEF) && ++ (typedef_type = check_typedef(nextfield->type))) ++ req->member_length = TYPE_LENGTH(typedef_type); +diff --git a/gdb_interface.c b/gdb_interface.c +index 3cf99c1b6529..608da86058c2 100755 +--- a/gdb_interface.c ++++ b/gdb_interface.c +@@ -512,6 +512,10 @@ dump_gnu_request(struct gnu_request *req, int in_gdb) + console("member_offset: %ld\n", req->member_offset); + console("member_length: %ld\n", req->member_length); + console("member_typecode: %d\n", req->member_typecode); ++ console("member_main_type_name: %s\n", req->member_main_type_name); ++ console("member_main_type_tag_name: %s\n", req->member_main_type_tag_name); ++ console("member_target_type_name: %s\n", req->member_target_type_name); ++ console("member_target_type_tag_name: %s\n", req->member_target_type_tag_name); + console("value: %lx ", req->value); + console("tagname: \"%s\" ", req->tagname); + console("pc: %lx ", req->pc); +diff --git a/symbols.c b/symbols.c +index 7966f129f80f..b1164613e342 100644 +--- a/symbols.c ++++ b/symbols.c +@@ -5447,6 +5447,7 @@ datatype_init(void) + * #define MEMBER_EXISTS(X,Y) (datatype_info((X), (Y), NULL) >= 0) + * #define MEMBER_SIZE(X,Y) datatype_info((X), (Y), MEMBER_SIZE_REQUEST) + * #define MEMBER_TYPE(X,Y) datatype_info((X), (Y), MEMBER_TYPE_REQUEST) ++ * #define MEMBER_TYPE_NAME(X,Y) datatype_info((X), (Y), MEMBER_TYPE_NAME_REQUEST) + * #define ANON_MEMBER_OFFSET(X,Y) datatype_info((X), (Y), ANON_MEMBER_OFFSET_REQUEST) + * + * to determine structure or union sizes, or member offsets. +@@ -5473,9 +5474,9 @@ datatype_info(char *name, char *member, struct datatype_member *dm) + req->fp = pc->nullfp; + + gdb_interface(req); +- if (req->flags & GNU_COMMAND_FAILED) { ++ if (req->flags & GNU_COMMAND_FAILED) { + FREEBUF(req); +- return -1; ++ return (dm == MEMBER_TYPE_NAME_REQUEST) ? 0 : -1; + } + + if (!req->typecode) { +@@ -5591,7 +5592,7 @@ datatype_info(char *name, char *member, struct datatype_member *dm) + FREEBUF(req); + + if (dm && (dm != MEMBER_SIZE_REQUEST) && (dm != MEMBER_TYPE_REQUEST) && +- (dm != STRUCT_SIZE_REQUEST)) { ++ (dm != STRUCT_SIZE_REQUEST) && (dm != MEMBER_TYPE_NAME_REQUEST)) { + dm->type = type_found; + dm->size = size; + dm->member_size = member_size; +@@ -5606,14 +5607,25 @@ datatype_info(char *name, char *member, struct datatype_member *dm) + } + } + +- if (!type_found) +- return -1; ++ if (!type_found) ++ return (dm == MEMBER_TYPE_NAME_REQUEST) ? 0 : -1; + + if (dm == MEMBER_SIZE_REQUEST) + return member_size; + else if (dm == MEMBER_TYPE_REQUEST) + return member_typecode; +- else if (dm == STRUCT_SIZE_REQUEST) { ++ else if (dm == MEMBER_TYPE_NAME_REQUEST) { ++ if (req->member_main_type_name) ++ return (ulong)req->member_main_type_name; ++ else if (req->member_main_type_tag_name) ++ return (ulong)req->member_main_type_tag_name; ++ else if (req->member_target_type_name) ++ return (ulong)req->member_target_type_name; ++ else if (req->member_target_type_tag_name) ++ return (ulong)req->member_target_type_tag_name; ++ else ++ return 0; ++ } else if (dm == STRUCT_SIZE_REQUEST) { + if ((req->typecode == TYPE_CODE_STRUCT) || + (req->typecode == TYPE_CODE_UNION) || + req->is_typedef) +commit a812e59a175c8c6197ae3dc78bd5e1613adcc57c +Author: Dave Anderson +Date: Fri Aug 2 12:03:40 2019 -0400 + + Fix for the "timer" command in RHEL7.6 and later RHEL7 kernels. + Without the patch, the command emits extra faulty timer entries + because the tvec_root.vec[] and tvec.vec[] arrays are tracked using + hlist_head structures where list_head structures should be used. + (k-hagio@ab.jp.nec.com) + +diff --git a/kernel.c b/kernel.c +index 3cd5bf1aab73..1ef063226041 100644 +--- a/kernel.c ++++ b/kernel.c +@@ -53,7 +53,7 @@ static void dump_timer_data_timer_bases(const ulong *cpus); + struct tv_range; + static void init_tv_ranges(struct tv_range *, int, int, int); + static int do_timer_list(ulong,int, ulong *, void *,ulong *,struct tv_range *); +-static int do_timer_list_v3(ulong, int, ulong *, void *,ulong *); ++static int do_timer_list_v3(ulong, int, ulong *, void *,ulong *, long); + struct timer_bases_data; + static int do_timer_list_v4(struct timer_bases_data *); + static int compare_timer_data(const void *, const void *); +@@ -8237,7 +8237,12 @@ dump_timer_data_tvec_bases_v3(const ulong *cpus) + char buf3[BUFSIZE]; + + vec_root_size = vec_size = 0; +- head_size = SIZE(hlist_head); ++ ++ if (STREQ(MEMBER_TYPE_NAME("tvec_root", "vec"), "list_head")) ++ /* for RHEL7.6 or later */ ++ head_size = SIZE(list_head); ++ else ++ head_size = SIZE(hlist_head); + + if ((i = get_array_length("tvec_root.vec", NULL, head_size))) + vec_root_size = i; +@@ -8275,15 +8280,15 @@ next_cpu: + init_tv_ranges(tv, vec_root_size, vec_size, cpu); + + count += do_timer_list_v3(tv[1].base + OFFSET(tvec_root_s_vec), +- vec_root_size, vec, NULL, NULL); ++ vec_root_size, vec, NULL, NULL, head_size); + count += do_timer_list_v3(tv[2].base + OFFSET(tvec_s_vec), +- vec_size, vec, NULL, NULL); ++ vec_size, vec, NULL, NULL, head_size); + count += do_timer_list_v3(tv[3].base + OFFSET(tvec_s_vec), +- vec_size, vec, NULL, NULL); ++ vec_size, vec, NULL, NULL, head_size); + count += do_timer_list_v3(tv[4].base + OFFSET(tvec_s_vec), +- vec_size, vec, NULL, NULL); ++ vec_size, vec, NULL, NULL, head_size); + count += do_timer_list_v3(tv[5].base + OFFSET(tvec_s_vec), +- vec_size, vec, NULL, NULL); ++ vec_size, vec, NULL, NULL, head_size); + + if (count) + td = (struct timer_data *) +@@ -8293,15 +8298,15 @@ next_cpu: + get_symbol_data("jiffies", sizeof(ulong), &jiffies); + + do_timer_list_v3(tv[1].base + OFFSET(tvec_root_s_vec), +- vec_root_size, vec, (void *)td, &highest); ++ vec_root_size, vec, (void *)td, &highest, head_size); + do_timer_list_v3(tv[2].base + OFFSET(tvec_s_vec), +- vec_size, vec, (void *)td, &highest); ++ vec_size, vec, (void *)td, &highest, head_size); + do_timer_list_v3(tv[3].base + OFFSET(tvec_s_vec), +- vec_size, vec, (void *)td, &highest); ++ vec_size, vec, (void *)td, &highest, head_size); + do_timer_list_v3(tv[4].base + OFFSET(tvec_s_vec), +- vec_size, vec, (void *)td, &highest); ++ vec_size, vec, (void *)td, &highest, head_size); + tdx = do_timer_list_v3(tv[5].base + OFFSET(tvec_s_vec), +- vec_size, vec, (void *)td, &highest); ++ vec_size, vec, (void *)td, &highest, head_size); + + qsort(td, tdx, sizeof(struct timer_data), compare_timer_data); + +@@ -8627,7 +8632,8 @@ do_timer_list_v3(ulong vec_kvaddr, + int size, + ulong *vec, + void *option, +- ulong *highest) ++ ulong *highest, ++ long head_size) + { + int i, t; + int count, tdx; +@@ -8645,19 +8651,24 @@ do_timer_list_v3(ulong vec_kvaddr, + tdx++; + } + +- readmem(vec_kvaddr, KVADDR, vec, SIZE(hlist_head) * size, ++ readmem(vec_kvaddr, KVADDR, vec, head_size * size, + "timer_list vec array", FAULT_ON_ERROR); + + ld = &list_data; + timer_list_buf = GETBUF(SIZE(timer_list)); + +- for (i = count = 0; i < size; i++, vec_kvaddr += SIZE(hlist_head)) { ++ for (i = count = 0; i < size; i++, vec_kvaddr += head_size) { + +- if (vec[i] == 0) +- continue; ++ if (head_size == SIZE(list_head)) { ++ if (vec[i*2] == vec_kvaddr) ++ continue; ++ } else { ++ if (vec[i] == 0) ++ continue; ++ } + + BZERO(ld, sizeof(struct list_data)); +- ld->start = vec[i]; ++ ld->start = (head_size == SIZE(list_head)) ? vec[i*2] : vec[i]; + ld->list_head_offset = OFFSET(timer_list_entry); + ld->end = vec_kvaddr; + ld->flags = RETURN_ON_LIST_ERROR; + diff --git a/SPECS/crash.spec b/SPECS/crash.spec index 062b9a0..eaee5c5 100644 --- a/SPECS/crash.spec +++ b/SPECS/crash.spec @@ -4,7 +4,7 @@ Summary: Kernel analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles Name: crash Version: 7.2.3 -Release: 10%{?dist} +Release: 11%{?dist} License: GPLv3 Group: Development/Debuggers Source: http://people.redhat.com/anderson/crash-%{version}.tar.gz @@ -29,6 +29,7 @@ Patch11: github_7e393689_ppc64_bt_user_space.patch Patch12: github_6596f112_alternate_list_loop_detect.patch Patch13: github_0f65ae0c_readline_tab_completion.patch Patch14: github_6b93714b_cmdline.patch +Patch15: github_f701ecad_a812e59a_timer_rhel7.6.patch %description The core analysis suite is a self-contained tool that can be used to @@ -64,6 +65,7 @@ offered by Mission Critical Linux, or the LKCD kernel patch. %patch12 -p1 -b github_6596f112_alternate_list_loop_detect.patch %patch13 -p1 -b github_0f65ae0c_readline_tab_completion.patch %patch14 -p1 -b github_6b93714b_cmdline.patch +%patch15 -p1 -b github_f701ecad_a812e59a_timer_rhel7.6.patch %build make RPMPKG="%{version}-%{release}" CFLAGS="%{optflags}" @@ -92,6 +94,10 @@ rm -rf %{buildroot} %{_includedir}/* %changelog +* Tue Mar 31 2019 Dave Anderson - 7.2.3-11 +- Fix to prevent display of invalid "timer" command entries + Resolves: rhbz#1818084 + * Tue Jan 8 2019 Dave Anderson - 7.2.3-10 - Restrict command line to 1500 bytes Resolves: rhbz#1663792