Subject: skipping more stuff in coredumps
To: None <tech-kern@netbsd.org>
From: Chuck Silvers <chuq@chuq.com>
List: tech-kern
Date: 01/16/2005 17:35:40
--DocE+STaALJfprDB
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

hi,

a while back someone mentioned the idea of having the coredump code not dump
regions of an address space that have been mapped but never used.  a common
example of this these days is pthread stacks.  I noticed this recently when
firefox dumped core and the resulting file was 1.2 GB (I set my stack limit
as high as it will go for historical reasons).

I've attached a patch to implement this.  I simplified the stack part
since it doesn't seem to me that the traditional stack region should be
treated different from anything else with the new algorithm (other than
being marked as "stack").

anyone see any problems with this?

-Chuck

--DocE+STaALJfprDB
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="diff.uvm_glue.c.4"

Index: src/sys/uvm/uvm_glue.c
===================================================================
RCS file: /cvsroot/src/sys/uvm/uvm_glue.c,v
retrieving revision 1.81
diff -u -p -r1.81 uvm_glue.c
--- src/sys/uvm/uvm_glue.c	12 May 2004 20:09:51 -0000	1.81
+++ src/sys/uvm/uvm_glue.c	16 Jan 2005 23:55:31 -0000
@@ -732,37 +732,30 @@ uvm_coredump_walkmap(p, vp, cred, func, 
 		if (entry == &map->header)
 			break;
 
-		/* Should never happen for a user process. */
-		if (UVM_ET_ISSUBMAP(entry))
-			panic("uvm_coredump_walkmap: user process with "
-			    "submap?");
-
 		state.cookie = cookie;
 		state.start = entry->start;
 		state.end = entry->end;
 		state.prot = entry->protection;
 		state.flags = 0;
 
-		if (state.start >= VM_MAXUSER_ADDRESS)
-			continue;
-
-		if (state.end > VM_MAXUSER_ADDRESS)
-			state.end = VM_MAXUSER_ADDRESS;
-
-		if (state.start >= (vaddr_t)vm->vm_maxsaddr) {
-			if (state.end <= maxstack)
-				continue;
-			if (state.start < maxstack)
-				state.start = maxstack;
-			state.flags |= UVM_COREDUMP_STACK;
+		KASSERT(!UVM_ET_ISSUBMAP(entry));
+		KASSERT(state.start < VM_MAXUSER_ADDRESS);
+		KASSERT(state.end <= VM_MAXUSER_ADDRESS);
+		if (entry->object.uvm_obj == NULL &&
+		    entry->aref.ar_amap == NULL) {
+			state.flags |= UVM_COREDUMP_NODUMP;
 		}
-
-		if ((entry->protection & VM_PROT_WRITE) == 0)
+		if ((entry->protection & VM_PROT_WRITE) == 0 &&
+		    entry->aref.ar_amap == NULL) {
 			state.flags |= UVM_COREDUMP_NODUMP;
-
+		}
 		if (entry->object.uvm_obj != NULL &&
-		    UVM_OBJ_IS_DEVICE(entry->object.uvm_obj))
+		    entry->object.uvm_obj->pgops == &uvm_deviceops) {
 			state.flags |= UVM_COREDUMP_NODUMP;
+		}
+		if (state.start >= (vaddr_t)vm->vm_maxsaddr) {
+			state.flags |= UVM_COREDUMP_STACK;
+		}
 
 		vm_map_unlock_read(map);
 		error = (*func)(p, vp, cred, &state);

--DocE+STaALJfprDB--