[Crash-utility] [PATCH] Fix for "kmem <addr>" for kernels configured with CONFIG_SLUB and SLAB_RED_ZONE.
OGAWA Hirofumi
hirofumi at mail.parknet.co.jp
Fri Feb 3 20:41:55 UTC 2017
Dave Anderson <anderson at redhat.com> writes:
> Hello Ogawa,
Hello,
> Attached is a patch for your review. You will have to
> enter "set redzone on" in order for the adjusted object
> addresses to be displayed.
Thanks! This seems to be what I want.
> diff --git a/defs.h b/defs.h
> index 68ed4d4..9b689b7 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -536,6 +536,7 @@ struct program_context {
> #define EXCLUDED_VMEMMAP (0x40000ULL)
> #define is_excluded_vmemmap() (pc->flags2 & EXCLUDED_VMEMMAP)
> #define MEMSRC_LOCAL (0x80000ULL)
> +#define REDZONE (0x100000ULL)
> char *cleanup;
> char *namelist_orig;
> char *namelist_debug_orig;
> @@ -1979,6 +1980,7 @@ struct offset_table { /* stash of commonly-used offsets */
> long task_struct_stack;
> long tnt_mod;
> long radix_tree_node_shift;
> + long kmem_cache_red_left_pad;
> };
>
> struct size_table { /* stash of commonly-used sizes */
> diff --git a/help.c b/help.c
> index 35cd941..50b2c29 100644
> --- a/help.c
> +++ b/help.c
> @@ -1072,8 +1072,12 @@ char *help_set[] = {
> " must be a kernel or module text address, which",
> " may be expressed symbolically or as a hexadecimal",
> " value.",
> -" offline show | hide Show or hide command output that is associated",
> +" offline show | hide show or hide command output that is associated",
> " with offline cpus.",
> +" redzone on | off if on, CONFIG_SLUB object addresses displayed by",
> +" the kmem command will be adjusted to reflect the",
> +" SLAB_RED_ZONE padding inserted at the beginning",
> +" of the object.",
> " ",
> " Internal variables may be set in four manners:\n",
> " 1. entering the set command in $HOME/.%src.",
> @@ -1124,6 +1128,7 @@ char *help_set[] = {
> " gdb: off",
> " scope: (not set)",
> " offline: show",
> +" redzone: off",
> " ",
> " Show the current context:\n",
> " %s> set",
> diff --git a/main.c b/main.c
> index 05c2042..6ab260d 100644
> --- a/main.c
> +++ b/main.c
> @@ -1469,6 +1469,8 @@ dump_program_context(void)
> fprintf(fp, "%sSNAP", others++ ? "|" : "");
> if (pc->flags2 & EXCLUDED_VMEMMAP)
> fprintf(fp, "%sEXCLUDED_VMEMMAP", others++ ? "|" : "");
> + if (pc->flags2 & REDZONE)
> + fprintf(fp, "%sREDZONE", others++ ? "|" : "");
> fprintf(fp, ")\n");
>
> fprintf(fp, " namelist: %s\n", pc->namelist);
> diff --git a/memory.c b/memory.c
> index 774d090..128ed3f 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -723,6 +723,7 @@ vm_init(void)
> MEMBER_OFFSET_INIT(kmem_cache_node, "kmem_cache", "node");
> MEMBER_OFFSET_INIT(kmem_cache_cpu_slab, "kmem_cache", "cpu_slab");
> MEMBER_OFFSET_INIT(kmem_cache_list, "kmem_cache", "list");
> + MEMBER_OFFSET_INIT(kmem_cache_red_left_pad, "kmem_cache", "red_left_pad");
> MEMBER_OFFSET_INIT(kmem_cache_name, "kmem_cache", "name");
> MEMBER_OFFSET_INIT(kmem_cache_flags, "kmem_cache", "flags");
> MEMBER_OFFSET_INIT(kmem_cache_cpu_freelist, "kmem_cache_cpu", "freelist");
> @@ -18357,6 +18358,7 @@ do_slab_slub(struct meminfo *si, int verbose)
> ulong freelist, cpu_freelist, cpu_slab_ptr;
> int i, free_objects, cpu_slab, is_free, node;
> ulong p, q;
> + ulong red_left_pad;
>
> if (!si->slab) {
> if (CRASHDEBUG(1))
> @@ -18442,6 +18444,15 @@ do_slab_slub(struct meminfo *si, int verbose)
> fprintf(fp, "< SLUB: free list END (%d found) >\n", i);
> }
>
> + if (VALID_MEMBER(kmem_cache_red_left_pad)) {
> +#define SLAB_RED_ZONE 0x00000400UL
> + ulong flags = ULONG(si->cache_buf + OFFSET(kmem_cache_flags));
> + red_left_pad = ULONG(si->cache_buf + OFFSET(kmem_cache_red_left_pad));
> + if (flags & SLAB_RED_ZONE)
> + vaddr += red_left_pad;
> + } else
> + red_left_pad = 0;
> +
> for (p = vaddr; p < vaddr + objects * si->size; p += si->size) {
> hq_open();
> is_free = FALSE;
> @@ -18482,7 +18493,8 @@ do_slab_slub(struct meminfo *si, int verbose)
>
> fprintf(fp, " %s%lx%s",
> is_free ? " " : "[",
> - p, is_free ? " " : "]");
> + pc->flags2 & REDZONE ? p : p - red_left_pad,
> + is_free ? " " : "]");
> if (is_free && (cpu_slab >= 0))
> fprintf(fp, "(cpu %d cache)", cpu_slab);
> fprintf(fp, "\n");
> diff --git a/symbols.c b/symbols.c
> index c6d1a6a..1d8dd13 100644
> --- a/symbols.c
> +++ b/symbols.c
> @@ -9332,6 +9332,8 @@ dump_offset_table(char *spec, ulong makestruct)
> OFFSET(kmem_cache_name));
> fprintf(fp, " kmem_cache_list: %ld\n",
> OFFSET(kmem_cache_list));
> + fprintf(fp, " kmem_cache_red_left_pad: %ld\n",
> + OFFSET(kmem_cache_red_left_pad));
> fprintf(fp, " kmem_cache_node: %ld\n",
> OFFSET(kmem_cache_node));
> fprintf(fp, " kmem_cache_cpu_slab: %ld\n",
> diff --git a/tools.c b/tools.c
> index 494af07..01b52cd 100644
> --- a/tools.c
> +++ b/tools.c
> @@ -2435,6 +2435,31 @@ cmd_set(void)
>
> return;
>
> + } else if (STREQ(args[optind], "redzone")) {
> + if (args[optind+1]) {
> + optind++;
> + if (STREQ(args[optind], "on"))
> + pc->flags2 |= REDZONE;
> + else if (STREQ(args[optind], "off"))
> + pc->flags2 &= ~REDZONE;
> + else if (IS_A_NUMBER(args[optind])) {
> + value = stol(args[optind],
> + FAULT_ON_ERROR, NULL);
> + if (value)
> + pc->flags2 |= REDZONE;
> + else
> + pc->flags2 &= ~REDZONE;
> + } else
> + goto invalid_set_command;
> + }
> +
> + if (runtime) {
> + fprintf(fp, "redzone: %s\n",
> + pc->flags2 & REDZONE ?
> + "on" : "off");
> + }
> + return;
> +
> } else if (XEN_HYPER_MODE()) {
> error(FATAL, "invalid argument for the Xen hypervisor\n");
> } else if (pc->flags & MINIMAL_MODE) {
> @@ -2541,6 +2566,7 @@ show_options(void)
> else
> fprintf(fp, "(not set)\n");
> fprintf(fp, " offline: %s\n", pc->flags2 & OFFLINE_HIDE ? "hide" : "show");
> + fprintf(fp, " redzone: %s\n", pc->flags2 & REDZONE ? "on" : "off");
> }
--
OGAWA Hirofumi <hirofumi at mail.parknet.co.jp>
More information about the Crash-utility
mailing list