[Crash-utility] cannot load slab info from 3.11 dump because of invalid pointer in kmem_cache

Dave Anderson anderson at redhat.com
Wed Aug 21 20:56:46 UTC 2013



----- Original Message -----
> 
> ----- Original Message -----
>
> > If this is a memory corruption in one of the slab, would it be better
> > if "crash" just skipped this slab (or marked it as 'fail to load') and
> > show info for the rest of caches?
> 
> I suppose that could be done, but there is no recording of the kmem_cache
> slab list entries during intialization, so there's currently nothing that
> could be "marked".  But perhaps a list of "bad" slab caches could be created
> by kmem_cache_init() which could be consulted later when "kmem -[sS]" cycle
> through the slab list.

If your problem is due to slab cache corruption, would something like
the attached (and inlined) patch work for you?

--- crash-7.0.1/defs.h.orig
+++ crash-7.0.1/defs.h
@@ -2183,6 +2183,8 @@ struct vm_table {                /* kern
 	int cpu_slab_type;
 	int nr_vm_event_items;
 	char **vm_event_items;
+	int nr_bad_slab_caches;
+	ulong *bad_slab_caches;
 };
 
 #define NODES                       (0x1)
--- crash-7.0.1/memory.c.orig
+++ crash-7.0.1/memory.c
@@ -8412,6 +8412,43 @@ kmem_cache_downsize(void)
 	FREEBUF(cache_buf);
 }
 
+/*
+ *  Stash a list of presumably-corrupted slab cache addresses.
+ */
+static void
+mark_bad_slab_cache(ulong cache) 
+{
+	size_t sz;
+
+	if (vt->nr_bad_slab_caches) {
+		sz = sizeof(ulong) * (vt->nr_bad_slab_caches + 1);
+		if (!(vt->bad_slab_caches = realloc(vt->bad_slab_caches, sz))) {
+                	error(INFO, "cannot realloc bad_slab_caches array\n");
+			vt->nr_bad_slab_caches = 0;
+			return;
+		}
+	} else {
+		if (!(vt->bad_slab_caches = (ulong *)malloc(sizeof(ulong)))) {
+			error(INFO, "cannot malloc bad_slab_caches array\n");
+			return;
+		}
+	}
+
+	vt->bad_slab_caches[vt->nr_bad_slab_caches++] = cache;
+}
+
+static int
+bad_slab_cache(ulong cache) 
+{
+	int i;
+
+	for (i = 0; i < vt->nr_bad_slab_caches; i++) {
+		if (vt->bad_slab_caches[i] == cache)
+			return TRUE;
+	}
+
+       return FALSE;
+}
 
 /*
  *  Determine the largest cpudata limit for a given cache.
@@ -8507,8 +8544,13 @@ kmem_cache_s_array_nodes:
 	for (i = max_limit = 0; (i < kt->cpus) && cpudata[i]; i++) {
                 if (!readmem(cpudata[i]+OFFSET(array_cache_limit),
                     KVADDR, &limit, sizeof(int),
-                    "array cache limit", RETURN_ON_ERROR))
-			goto bail_out;
+                    "array cache limit", RETURN_ON_ERROR)) {
+			error(INFO, 
+			    "kmem_cache: %lx: invalid array_cache pointer: %lx\n",
+				cache, cpudata[i]);
+			mark_bad_slab_cache(cache);
+			return max_limit;
+		}
 		if (CRASHDEBUG(3))
 			fprintf(fp, "  array limit[%d]: %d\n", i, limit);
                 if (limit > max_limit)
@@ -9213,6 +9255,11 @@ dump_kmem_cache_percpu_v2(struct meminfo
                         goto next_cache;
                 }
 
+		if (bad_slab_cache(si->cache)) {
+                        fprintf(fp, "%lx %-18s [INVALID/CORRUPTED]\n", si->cache, buf);
+                        goto next_cache;
+		}
+
 		si->curname = buf;
 
 	        readmem(si->cache+OFFSET(kmem_cache_s_objsize),
@@ -11728,6 +11775,15 @@ dump_vm_table(int verbose)
 	fprintf(fp, "   kmem_cache_count: %ld\n", vt->kmem_cache_count);
 	fprintf(fp, " kmem_cache_namelen: %d\n", vt->kmem_cache_namelen);
 	fprintf(fp, "kmem_cache_len_nodes: %ld\n", vt->kmem_cache_len_nodes);
+	fprintf(fp, " nr_bad_slab_caches: %d\n", vt->nr_bad_slab_caches);
+	if (!vt->nr_bad_slab_caches)
+		fprintf(fp, "    bad_slab_caches: (unused)\n");
+	else {
+		for (i = 0; i < vt->nr_bad_slab_caches; i++) {
+			fprintf(fp, " bad_slab_caches[%d]: %lx\n", 
+				i, vt->bad_slab_caches[i]);
+		}
+	}
 	fprintf(fp, "        PG_reserved: %lx\n", vt->PG_reserved);
 	fprintf(fp, "            PG_slab: %ld (%lx)\n", vt->PG_slab, 
 		(ulong)1 << vt->PG_slab);

Thanks,
  Dave
-------------- next part --------------
A non-text attachment was scrubbed...
Name: slab.patch
Type: text/x-patch
Size: 3052 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/crash-utility/attachments/20130821/73eba534/attachment.bin>


More information about the Crash-utility mailing list