[issue827] kernel panic on HEAD

Matthew Dillon dillon at apollo.backplane.com
Mon Oct 20 17:32:52 PDT 2008

:This looks like it could be easy (for you anyway) to fix...Just wanted
:to make sure you've seen it.
:#15 0xc03101b7 in calltrap () at /usr/src/sys/platform/pc32/i386/exception.=
:#16 0xc01a5e09 in fill_kinfo_proc (p=3D0xda308598, kp=3D0xee07664c) at
:#17 0xc01ac836 in sysctl_out_proc (p=3D0xda308598, req=3D0xee076c00, flags=
:=3D0) at
:#18 0xc01ad2a8 in sysctl_kern_proc (oidp=3D0xc0394620, arg1=3D0x0, arg2=3D0,
:req=3D0xee076c00) at /usr/src/sys/kern/kern_proc.c:779
:(kgdb) print p->p_sigacts=20
:$3 =3D (struct sigacts *) 0xdeadc0de

    Ah, that post occured while I was away, I missed it.

    Well, the proc structure has clearly been deallocated.  We already put
    a PHOLD() in the loop.  Clearly that is not doing the job.  I see two

    (1) The code in kern_exit() is blocking after the ref count loop
	that waits for all holds to be released, before removing the
	process from the allproc or zombproc list.

    (2) the LIST_FOREACH_MUTABLE() in kern_proc.c is broken.

    It could even be both.  the LIST_FOREACH_MUTABLE is clearly broken.
    It is saving the 'next' process (np) for the next loop, but it is not
    protecting it.  And in the kern_exit() case the code is complex enough
    that something might block there too.

    Please try this patch.  Oddly enough 'p' is being protected by the
    PHOLD/PRELE through possible blocking conditions in the sysctl code,
    but 'np' is not being protected, so making it LIST_FOREACH instead
    of LIST_FOREACH_MUTABLE should solve that particular problem.

    I'm not sure about (1).  The code is certainly fragile so I have added
    an assertion to catch the case if it occurs there.

					Matthew Dillon 
					<dillon at backplane.com>

Index: kern_exit.c
RCS file: /cvs/src/sys/kern/kern_exit.c,v
retrieving revision 1.91
diff -u -p -r1.91 kern_exit.c
--- kern_exit.c	18 May 2008 20:02:02 -0000	1.91
+++ kern_exit.c	21 Oct 2008 00:21:21 -0000
@@ -824,6 +824,7 @@ loop:
 			 * Finally finished with old proc entry.
 			 * Unlink it from its process group and free it.
+			KKASSERT(p->p_lock == 0);
Index: kern_proc.c
RCS file: /cvs/src/sys/kern/kern_proc.c,v
retrieving revision 1.45
diff -u -p -r1.45 kern_proc.c
--- kern_proc.c	12 Jun 2008 23:25:02 -0000	1.45
+++ kern_proc.c	21 Oct 2008 00:22:07 -0000
@@ -689,7 +689,7 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS)
 	int *name = (int*) arg1;
 	int oid = oidp->oid_number;
 	u_int namelen = arg2;
-	struct proc *p, *np;
+	struct proc *p;
 	struct proclist *plist;
 	struct thread *td;
 	int doingzomb, flags = 0;
@@ -728,7 +728,7 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS)
 			plist = &zombproc;
 			plist = &allproc;
-		LIST_FOREACH_MUTABLE(p, plist, p_list, np) {
+		LIST_FOREACH(p, plist, p_list) {
 			 * Show a user only their processes.

More information about the Bugs mailing list