Dave Anderson <anderson(a)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(a)mail.parknet.co.jp>