This patch will remove all kernel structures, and leave them to be blank for debug purpose. There seems to be a lot of code changes, but most are rewriting struct member resolving into crash way. Signed-off-by: Tao Liu <ltao@xxxxxxxxxx> --- defs.h | 20 +++++- maple_tree.c | 183 ++++++++++++++++++++++++++++++++------------------- maple_tree.h | 92 ++++++-------------------- memory.c | 4 ++ 4 files changed, 159 insertions(+), 140 deletions(-) diff --git a/defs.h b/defs.h index d4be477..8ea710f 100644 --- a/defs.h +++ b/defs.h @@ -1332,7 +1332,6 @@ struct offset_table { /* stash of commonly-used offsets */ long percpu_struct_halt_ra; long percpu_struct_halt_pv; long mm_struct_mmap; - long mm_struct_mm_mt; long mm_struct_pgd; long mm_struct_rss; long mm_struct_anon_rss; @@ -2182,6 +2181,23 @@ struct offset_table { /* stash of commonly-used offsets */ long blk_mq_tags_nr_reserved_tags; long blk_mq_tags_rqs; long request_queue_hctx_table; + + long mm_struct_mm_mt; + long maple_tree_ma_root; + long maple_tree_ma_flags; + long maple_node_parent; + long maple_node_ma64; + long maple_node_mr64; + long maple_node_slot; + long maple_arange_64_parent; + long maple_arange_64_pivot; + long maple_arange_64_slot; + long maple_arange_64_meta; + long maple_range_64_parent; + long maple_range_64_pivot; + long maple_range_64_slot; + long maple_range_64_meta; + long maple_metadata_end; }; struct size_table { /* stash of commonly-used sizes */ @@ -2352,6 +2368,8 @@ struct size_table { /* stash of commonly-used sizes */ long sbitmap_queue; long sbq_wait_state; long blk_mq_tags; + long maple_tree_struct; + long maple_node_struct; }; struct array_table { diff --git a/maple_tree.c b/maple_tree.c index 21a2226..ff07d58 100644 --- a/maple_tree.c +++ b/maple_tree.c @@ -78,10 +78,11 @@ static inline enum maple_type mte_node_type(const struct maple_enode *entry) static inline void *mas_root(struct ma_state *mas) { - struct maple_tree tree; - readmem(mas->tree, KVADDR, &tree, sizeof(tree), + char tree[SIZE(maple_tree_struct)]; + + readmem((ulonglong)(mas->tree), KVADDR, tree, SIZE(maple_tree_struct), "mas_root read maple_tree", FAULT_ON_ERROR); - return tree.ma_root; + return *(void **)(tree + OFFSET(maple_tree_ma_root)); } static inline struct maple_enode *mas_start(struct ma_state *mas) @@ -127,10 +128,12 @@ static inline unsigned long *ma_pivots(struct maple_node *node, { switch (type) { case maple_arange_64: - return node->ma64.pivot; + return (unsigned long *)((char *)node + OFFSET(maple_node_ma64) + + OFFSET(maple_arange_64_pivot)); case maple_range_64: case maple_leaf_64: - return node->mr64.pivot; + return (unsigned long *)((char *)node + OFFSET(maple_node_mr64) + + OFFSET(maple_range_64_pivot)); case maple_dense: return NULL; } @@ -142,9 +145,13 @@ static inline struct maple_metadata *ma_meta(struct maple_node *mn, { switch (mt) { case maple_arange_64: - return &mn->ma64.meta; + return (struct maple_metadata *)( + (char *)mn + OFFSET(maple_node_ma64) + + OFFSET(maple_arange_64_meta)); default: - return &mn->mr64.meta; + return (struct maple_metadata *)( + (char *)mn + OFFSET(maple_node_mr64) + + OFFSET(maple_range_64_meta)); } } @@ -153,7 +160,7 @@ static inline unsigned char ma_meta_end(struct maple_node *mn, { struct maple_metadata *meta = ma_meta(mn, mt); - return meta->end; + return *((char *)meta + OFFSET(maple_metadata_end)); } static inline unsigned char ma_data_end(struct maple_node *node, @@ -179,9 +186,10 @@ static inline unsigned char ma_data_end(struct maple_node *node, static inline bool ma_dead_node(const struct maple_node *node, const struct maple_node *orig_node) { - struct maple_node *parent = (void *)((unsigned long) - node->parent & ~MAPLE_NODE_MASK); - + struct maple_node *parent = (struct maple_node *) + (*(unsigned long *)((char *)node + + OFFSET(maple_node_parent)) + & ~MAPLE_NODE_MASK); return (parent == orig_node); } @@ -190,12 +198,14 @@ static inline void **ma_slots(struct maple_node *mn, enum maple_type mt) switch (mt) { default: case maple_arange_64: - return mn->ma64.slot; + return (void **)((char *)mn + OFFSET(maple_node_ma64) + + OFFSET(maple_arange_64_slot)); case maple_range_64: case maple_leaf_64: - return mn->mr64.slot; + return (void **)((char *)mn + OFFSET(maple_node_mr64) + + OFFSET(maple_range_64_slot)); case maple_dense: - return mn->slot; + return (void **)((char *)mn + OFFSET(maple_node_slot)); } } @@ -222,7 +232,7 @@ static inline void *mtree_range_walk(struct ma_state *mas) unsigned long max, min; unsigned long prev_max, prev_min; - struct maple_node tmp_node; + char tmp_node[SIZE(maple_node_struct)]; last = next = mas->node; prev_min = min = mas->min; @@ -232,11 +242,11 @@ static inline void *mtree_range_walk(struct ma_state *mas) last = next; node = mte_to_node(next); type = mte_node_type(next); - readmem(node, KVADDR, &tmp_node, sizeof(tmp_node), + readmem((ulonglong)node, KVADDR, tmp_node, SIZE(maple_node_struct), "mtree_range_walk read maple_node", FAULT_ON_ERROR); - pivots = ma_pivots(&tmp_node, type); - end = ma_data_end(&tmp_node, type, pivots, max); - if (ma_dead_node(&tmp_node, node)) + pivots = ma_pivots((struct maple_node *)tmp_node, type); + end = ma_data_end((struct maple_node *)tmp_node, type, pivots, max); + if (ma_dead_node((struct maple_node *)tmp_node, node)) goto dead_node; if (pivots[offset] >= mas->index) { @@ -257,9 +267,9 @@ static inline void *mtree_range_walk(struct ma_state *mas) max = pivots[offset]; next: - slots = ma_slots(&tmp_node, type); + slots = ma_slots((struct maple_node *)tmp_node, type); next = mt_slot(mas->tree, slots, offset); - if (ma_dead_node(&tmp_node, node)) + if (ma_dead_node((struct maple_node *)tmp_node, node)) goto dead_node; } while (!ma_is_leaf(type)); @@ -410,13 +420,16 @@ retry: static inline bool ma_is_root(struct maple_node *node) { - return ((unsigned long)node->parent & MA_ROOT_PARENT); + return (*(unsigned long *)((char *)node + + OFFSET(maple_node_parent)) + & MA_ROOT_PARENT); } static inline struct maple_node *mte_parent(const struct maple_node *node) { - return (void *)((unsigned long) - (node->parent) & ~MAPLE_NODE_MASK); + return (void *)(*(unsigned long *)((char *)node + + OFFSET(maple_node_parent)) + & ~MAPLE_NODE_MASK); } static inline unsigned long mte_parent_slot_mask(unsigned long parent) @@ -430,7 +443,9 @@ static inline unsigned long mte_parent_slot_mask(unsigned long parent) static inline bool mt_is_alloc(struct maple_tree *mt) { - return (mt->ma_flags & MT_FLAGS_ALLOC_RANGE); + return (*(unsigned int *)((char *)mt + + OFFSET(maple_tree_ma_flags)) + & MT_FLAGS_ALLOC_RANGE); } static inline @@ -438,7 +453,7 @@ enum maple_type mte_parent_enum(struct maple_enode *p_enode, struct maple_tree *mt) { unsigned long p_type; - struct maple_tree tmp_tree; + char tmp_tree[SIZE(maple_tree_struct)]; p_type = (unsigned long)p_enode; if (p_type & MAPLE_PARENT_ROOT) @@ -449,9 +464,9 @@ enum maple_type mte_parent_enum(struct maple_enode *p_enode, switch (p_type) { case MAPLE_PARENT_RANGE64: /* or MAPLE_PARENT_ARANGE64 */ - readmem(mt, KVADDR, &tmp_tree, sizeof(tmp_tree), + readmem((ulonglong)mt, KVADDR, tmp_tree, SIZE(maple_tree_struct), "mte_parent_enum read maple_tree", FAULT_ON_ERROR); - if (mt_is_alloc(&tmp_tree)) + if (mt_is_alloc((struct maple_tree *)tmp_tree)) return maple_arange_64; return maple_range_64; } @@ -462,7 +477,9 @@ enum maple_type mte_parent_enum(struct maple_enode *p_enode, static inline enum maple_type mas_parent_enum(struct ma_state *mas, struct maple_node *node) { - return mte_parent_enum(ma_enode_ptr(node->parent), mas->tree); + return mte_parent_enum(ma_enode_ptr(*(struct maple_pnode **) + ((char *)node + OFFSET(maple_node_parent))), + mas->tree); } static inline unsigned long mte_parent_shift(unsigned long parent) @@ -476,7 +493,8 @@ static inline unsigned long mte_parent_shift(unsigned long parent) static inline unsigned int mte_parent_slot(const struct maple_node *node) { - unsigned long val = (unsigned long) node->parent; + unsigned long val = *(unsigned long *)((char *)node + + OFFSET(maple_node_parent)); /* Root. */ if (val & 1) @@ -513,35 +531,36 @@ static int mas_ascend(struct ma_state *mas) unsigned long *pivots; unsigned char offset; bool set_max = false, set_min = false; - struct maple_node tmp_node; + + char tmp_node[SIZE(maple_node_struct)]; a_node = mas_mn(mas); - readmem(a_node, KVADDR, &tmp_node, sizeof(tmp_node), + readmem((ulonglong)a_node, KVADDR, tmp_node, SIZE(maple_node_struct), "mas_ascend read maple_node", FAULT_ON_ERROR); - if (ma_is_root(&tmp_node)) { + if (ma_is_root((struct maple_node *)tmp_node)) { mas->offset = 0; return 0; } - readmem(mte_to_node(mas->node), KVADDR, &tmp_node, sizeof(tmp_node), - "mas_ascend read maple_node", FAULT_ON_ERROR); - p_node = mte_parent(&tmp_node); + readmem((ulonglong)(mte_to_node(mas->node)), KVADDR, tmp_node, + SIZE(maple_node_struct), "mas_ascend read maple_node", FAULT_ON_ERROR); + p_node = mte_parent((struct maple_node *)tmp_node); if (a_node == p_node) return 1; - a_type = mas_parent_enum(mas, &tmp_node); - offset = mte_parent_slot(&tmp_node); + a_type = mas_parent_enum(mas, (struct maple_node *)tmp_node); + offset = mte_parent_slot((struct maple_node *)tmp_node); a_enode = mt_mk_node(p_node, a_type); /* Check to make sure all parent information is still accurate */ - if (p_node != mte_parent(&tmp_node)) + if (p_node != mte_parent((struct maple_node *)tmp_node)) return 1; mas->node = a_enode; mas->offset = offset; - readmem(mte_to_node(a_enode), KVADDR, &tmp_node, sizeof(tmp_node), - "mas_ascend read maple_node", FAULT_ON_ERROR); - if (mte_is_root(&tmp_node)) { + readmem((ulonglong)(mte_to_node(a_enode)), KVADDR, tmp_node, + SIZE(maple_node_struct), "mas_ascend read maple_node", FAULT_ON_ERROR); + if (mte_is_root((struct maple_node *)tmp_node)) { mas->max = ULONG_MAX; mas->min = 0; return 0; @@ -551,15 +570,16 @@ static int mas_ascend(struct ma_state *mas) max = ULONG_MAX; do { p_enode = a_enode; - readmem(mte_to_node(p_enode), KVADDR, &tmp_node, sizeof(tmp_node), + readmem((ulonglong)(mte_to_node(p_enode)), KVADDR, tmp_node, + SIZE(maple_node_struct), "mas_ascend read maple_node", FAULT_ON_ERROR); - a_type = mas_parent_enum(mas, &tmp_node); - a_node = mte_parent(&tmp_node); - a_slot = mte_parent_slot(&tmp_node); - readmem(a_node, KVADDR, &tmp_node, sizeof(tmp_node), + a_type = mas_parent_enum(mas, (struct maple_node *)tmp_node); + a_node = mte_parent((struct maple_node *)tmp_node); + a_slot = mte_parent_slot((struct maple_node *)tmp_node); + readmem((ulonglong)a_node, KVADDR, tmp_node, SIZE(maple_node_struct), "mas_ascend read maple_node", FAULT_ON_ERROR); - pivots = ma_pivots(&tmp_node, a_type); - a_enode = mt_mk_node(&tmp_node, a_type); + pivots = ma_pivots((struct maple_node *)tmp_node, a_type); + a_enode = mt_mk_node((struct maple_node *)tmp_node, a_type); if (!set_min && a_slot) { set_min = true; @@ -571,10 +591,10 @@ static int mas_ascend(struct ma_state *mas) max = pivots[a_slot]; } - if (ma_dead_node(&tmp_node, a_node)) + if (ma_dead_node((struct maple_node *)tmp_node, a_node)) return 1; - if (ma_is_root(&tmp_node)) + if (ma_is_root((struct maple_node *)tmp_node)) break; } while (!set_min || !set_max); @@ -595,16 +615,16 @@ static inline int mas_next_node(struct ma_state *mas, struct maple_node *node, enum maple_type mt; void **slots; - struct maple_node tmp_node; + char tmp_node[SIZE(maple_node_struct)]; if (mas->max >= max) goto no_entry; level = 0; - readmem(node, KVADDR, &tmp_node, sizeof(tmp_node), + readmem((ulonglong)node, KVADDR, tmp_node, SIZE(maple_node_struct), "mas_next_node read maple_node", FAULT_ON_ERROR); do { - if (ma_is_root(&tmp_node)) + if (ma_is_root((struct maple_node *)tmp_node)) goto no_entry; min = mas->max + 1; @@ -618,33 +638,33 @@ static inline int mas_next_node(struct ma_state *mas, struct maple_node *node, level++; node = mas_mn(mas); mt = mte_node_type(mas->node); - readmem(node, KVADDR, &tmp_node, sizeof(tmp_node), + readmem((ulonglong)node, KVADDR, tmp_node, SIZE(maple_node_struct), "mas_next_node read maple_node", FAULT_ON_ERROR); - pivots = ma_pivots(&tmp_node, mt); - } while (offset == ma_data_end(&tmp_node, mt, pivots, mas->max)); + pivots = ma_pivots((struct maple_node *)tmp_node, mt); + } while (offset == ma_data_end((struct maple_node *)tmp_node, mt, pivots, mas->max)); - slots = ma_slots(&tmp_node, mt); + slots = ma_slots((struct maple_node *)tmp_node, mt); pivot = mas_safe_pivot(mas, pivots, ++offset, mt); while (level > 1) { /* Descend, if necessary */ enode = mas_slot(mas, slots, offset); - if (ma_dead_node(&tmp_node, node)) + if (ma_dead_node((struct maple_node *)tmp_node, node)) return 1; mas->node = enode; level--; node = mas_mn(mas); mt = mte_node_type(mas->node); - readmem(node, KVADDR, &tmp_node, sizeof(tmp_node), + readmem((ulonglong)node, KVADDR, tmp_node, SIZE(maple_node_struct), "mas_next_node read maple_node", FAULT_ON_ERROR); - slots = ma_slots(&tmp_node, mt); - pivots = ma_pivots(&tmp_node, mt); + slots = ma_slots((struct maple_node *)tmp_node, mt); + pivots = ma_pivots((struct maple_node *)tmp_node, mt); offset = 0; pivot = pivots[0]; } enode = mas_slot(mas, slots, offset); - if (ma_dead_node(&tmp_node, node)) + if (ma_dead_node((struct maple_node *)tmp_node, node)) return 1; mas->node = enode; @@ -653,7 +673,7 @@ static inline int mas_next_node(struct ma_state *mas, struct maple_node *node, return 0; no_entry: - if (ma_dead_node(&tmp_node, node)) + if (ma_dead_node((struct maple_node *)tmp_node, node)) return 1; mas->node = MAS_NONE; @@ -669,7 +689,7 @@ static inline void *mas_next_entry(struct ma_state *mas, unsigned long limit) unsigned long last; enum maple_type mt; - struct maple_node tmp_node; + char tmp_node[SIZE(maple_node_struct)]; last = mas->last; retry: @@ -684,10 +704,10 @@ retry: } while (!mas_is_none(mas)) { - readmem(node, KVADDR, &tmp_node, sizeof(tmp_node), + readmem((ulonglong)node, KVADDR, tmp_node, SIZE(maple_node_struct), "mas_next_entry read maple_node", FAULT_ON_ERROR); - entry = mas_next_nentry(mas, &tmp_node, limit, mt, node); - if (ma_dead_node(&tmp_node, node)) { + entry = mas_next_nentry(mas, (struct maple_node *)tmp_node, limit, mt, node); + if (ma_dead_node((struct maple_node *)tmp_node, node)) { mas_rewalk(mas, last); goto retry; } @@ -771,4 +791,31 @@ void *mas_find(struct ma_state *mas, unsigned long max) /* Retries on dead nodes handled by mas_next_entry */ return mas_next_entry(mas, max); +} + +/***********************************************/ +void maple_init(void) +{ + STRUCT_SIZE_INIT(maple_tree_struct, "maple_tree"); + STRUCT_SIZE_INIT(maple_node_struct, "maple_node"); + + MEMBER_OFFSET_INIT(maple_tree_ma_root, "maple_tree", "ma_root"); + MEMBER_OFFSET_INIT(maple_tree_ma_flags, "maple_tree", "ma_flags"); + + MEMBER_OFFSET_INIT(maple_node_parent, "maple_node", "parent"); + MEMBER_OFFSET_INIT(maple_node_ma64, "maple_node", "ma64"); + MEMBER_OFFSET_INIT(maple_node_mr64, "maple_node", "mr64"); + MEMBER_OFFSET_INIT(maple_node_slot, "maple_node", "slot"); + + MEMBER_OFFSET_INIT(maple_arange_64_parent, "maple_arange_64", "parent"); + MEMBER_OFFSET_INIT(maple_arange_64_pivot, "maple_arange_64", "pivot"); + MEMBER_OFFSET_INIT(maple_arange_64_slot, "maple_arange_64", "slot"); + MEMBER_OFFSET_INIT(maple_arange_64_meta, "maple_arange_64", "meta"); + + MEMBER_OFFSET_INIT(maple_range_64_parent, "maple_range_64", "parent"); + MEMBER_OFFSET_INIT(maple_range_64_pivot, "maple_range_64", "pivot"); + MEMBER_OFFSET_INIT(maple_range_64_slot, "maple_range_64", "slot"); + MEMBER_OFFSET_INIT(maple_range_64_meta, "maple_range_64", "meta"); + + MEMBER_OFFSET_INIT(maple_metadata_end, "maple_metadata", "end"); } \ No newline at end of file diff --git a/maple_tree.h b/maple_tree.h index a5a131e..98f3c5c 100644 --- a/maple_tree.h +++ b/maple_tree.h @@ -7,29 +7,23 @@ * Authors: Liam R. Howlett <Liam.Howlett@xxxxxxxxxx> * Matthew Wilcox <willy@xxxxxxxxxxxxx> */ -#include <stdint.h> #include <stdbool.h> -typedef uint32_t spinlock_t; -typedef uint32_t lockdep_map_p; - -struct maple_tree { - union { - spinlock_t ma_lock; - lockdep_map_p ma_external_lock; - }; - void *ma_root; - unsigned int ma_flags; -}; +/* + * Keep the empty struct names for debug purpose of compiler warning. + * And can also keep the function prototypes consistent with kernel's + * corresponding functions. + */ +struct maple_tree { }; +struct maple_metadata { }; +struct maple_range_64 { }; +struct maple_arange_64 { }; +struct maple_alloc { }; +struct maple_node { }; typedef struct maple_enode *maple_enode; /* encoded node */ typedef struct maple_pnode *maple_pnode; /* parent node */ -struct maple_metadata { - unsigned char end; - unsigned char gap; -}; - struct ma_state { struct maple_tree *tree; /* The tree we're operating in */ unsigned long index; /* The index we're operating on - range start */ @@ -67,21 +61,28 @@ enum maple_type { .max = ULONG_MAX, \ } -#if defined(CONFIG_64BIT) || defined(BUILD_VDSO32_64) +#if defined(ALPHA) || defined(IA64) || \ + defined(S390) || defined(S390X) || \ + defined(PPC64) || defined(X86_64) || \ + defined(ARM64) || defined(SPARC64) || \ + defined(MIPS64) /* 64bit sizes */ #define MAPLE_NODE_SLOTS 31 /* 256 bytes including ->parent */ #define MAPLE_RANGE64_SLOTS 16 /* 256 bytes */ #define MAPLE_ARANGE64_SLOTS 10 /* 240 bytes */ #define MAPLE_ARANGE64_META_MAX 15 /* Out of range for metadata */ #define MAPLE_ALLOC_SLOTS (MAPLE_NODE_SLOTS - 1) -#else +#endif + +#if defined(X86) || defined(PPC) || \ + defined(ARM) || defined(MIPS) /* 32bit sizes */ #define MAPLE_NODE_SLOTS 63 /* 256 bytes including ->parent */ #define MAPLE_RANGE64_SLOTS 32 /* 256 bytes */ #define MAPLE_ARANGE64_SLOTS 21 /* 240 bytes */ #define MAPLE_ARANGE64_META_MAX 31 /* Out of range for metadata */ #define MAPLE_ALLOC_SLOTS (MAPLE_NODE_SLOTS - 2) -#endif /* defined(CONFIG_64BIT) || defined(BUILD_VDSO32_64) */ +#endif #define MAPLE_NODE_MASK 255UL @@ -101,56 +102,6 @@ enum maple_type { #define MAPLE_RESERVED_RANGE 4096 -typedef struct rcu_head { unsigned char x[16]; } rcu_head; - -struct maple_range_64 { - struct maple_pnode *parent; - unsigned long pivot[MAPLE_RANGE64_SLOTS - 1]; - union { - void *slot[MAPLE_RANGE64_SLOTS]; - struct { - void *pad[MAPLE_RANGE64_SLOTS - 1]; - struct maple_metadata meta; - }; - }; -}; - -struct maple_arange_64 { - struct maple_pnode *parent; - unsigned long pivot[MAPLE_ARANGE64_SLOTS - 1]; - void *slot[MAPLE_ARANGE64_SLOTS]; - unsigned long gap[MAPLE_ARANGE64_SLOTS]; - struct maple_metadata meta; -}; - -struct maple_alloc { - unsigned long total; - unsigned char node_count; - unsigned int request_count; - struct maple_alloc *slot[MAPLE_ALLOC_SLOTS]; -}; - -struct maple_node { - union { - struct { - struct maple_pnode *parent; - void *slot[MAPLE_NODE_SLOTS]; - }; - struct { - void *pad; - struct rcu_head rcu; - struct maple_enode *piv_parent; - unsigned char parent_slot; - enum maple_type type; - unsigned char slot_len; - unsigned int ma_flags; - }; - struct maple_range_64 mr64; - struct maple_arange_64 ma64; - struct maple_alloc alloc; - }; -}; - static inline void mas_reset(struct ma_state *mas) { mas->node = MAS_START; @@ -166,7 +117,6 @@ void mas_set_range(struct ma_state *mas, unsigned long start, unsigned long last static inline void mas_set(struct ma_state *mas, unsigned long index) { - mas_set_range(mas, index, index); } diff --git a/memory.c b/memory.c index 00f7c9a..2bfd5ae 100644 --- a/memory.c +++ b/memory.c @@ -299,6 +299,7 @@ static void dump_page_flags(ulonglong); static ulong kmem_cache_nodelists(ulong); static void dump_hstates(void); static ulong freelist_ptr(struct meminfo *, ulong, ulong); +extern void maple_init(void); /* * Memory display modes specific to this file. @@ -364,6 +365,9 @@ vm_init(void) MEMBER_OFFSET_INIT(task_struct_mm, "task_struct", "mm"); MEMBER_OFFSET_INIT(mm_struct_mmap, "mm_struct", "mmap"); MEMBER_OFFSET_INIT(mm_struct_mm_mt, "mm_struct", "mm_mt"); + if (VALID_MEMBER(mm_struct_mm_mt)) { + maple_init(); + } MEMBER_OFFSET_INIT(mm_struct_pgd, "mm_struct", "pgd"); MEMBER_OFFSET_INIT(mm_struct_rss, "mm_struct", "rss"); if (!VALID_MEMBER(mm_struct_rss)) -- 2.33.1 -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://listman.redhat.com/mailman/listinfo/crash-utility Contribution Guidelines: https://github.com/crash-utility/crash/wiki