:Matt,
:
:This looks like it could be easy (for you anyway) to fix...Just wanted
:to make sure you've seen it.
:
:--Peter
:...
:#15 0xc03101b7 in calltrap () at /usr/src/sys/platform/pc32/i386/exception.=
:s:785
:#16 0xc01a5e09 in fill_kinfo_proc (p=3D0xda308598, kp=3D0xee07664c) at
:/usr/src/sys/kern/kern_kinfo.c:88
:#17 0xc01ac836 in sysctl_out_proc (p=3D0xda308598, req=3D0xee076c00, flags=
:=3D0) at
:/usr/src/sys/kern/kern_proc.c:651
:#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
    possibilities:

    (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.

                                        -Matt
                                        Matthew Dillon 
                                        <[EMAIL PROTECTED]>

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);
                        proc_remove_zombie(p);
                        leavepgrp(p);
 
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;
                else
                        plist = &allproc;
-               LIST_FOREACH_MUTABLE(p, plist, p_list, np) {
+               LIST_FOREACH(p, plist, p_list) {
                        /*
                         * Show a user only their processes.
                         */

Reply via email to