From owner-freebsd-bugs Thu Jun 17 13:10: 5 1999 Delivered-To: freebsd-bugs@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (Postfix) with ESMTP id A82FD1560D for ; Thu, 17 Jun 1999 13:10:03 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id NAA86851; Thu, 17 Jun 1999 13:10:02 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Date: Thu, 17 Jun 1999 13:10:02 -0700 (PDT) Message-Id: <199906172010.NAA86851@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org Cc: From: Bruce Evans Subject: Re: kern/12247: userlevel program let kernel hang Reply-To: Bruce Evans Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org The following reply was made to PR kern/12247; it has been noted by GNATS. From: Bruce Evans To: dirk.meyer@dinoex.sub.org, FreeBSD-gnats-submit@FreeBSD.ORG Cc: Subject: Re: kern/12247: userlevel program let kernel hang Date: Fri, 18 Jun 1999 06:00:46 +1000 >>Description: > > while debugging a userlevel program > The user can hang the system, > no other processes seem to work. Try this fix. tsleep()'s return codes are poorly documented and were misinterpreted in lf_setlock(). tsleep() can return 0 if the process was restarted by a debugger, `so tsleep() != 0' is not the condition for the lock having been removed from the blocked list. Leaving the lock on the list corrupts the list. In your program, the corrupt list happens to be circular and this caused an endless loop in lf_wakelock() when the list is traversed. Bruce diff -c2 kern_lockf.c~ kern_lockf.c *** kern_lockf.c~ Sun May 9 20:42:39 1999 --- kern_lockf.c Fri Jun 18 05:37:00 1999 *************** *** 273,290 **** } #endif /* LOCKF_DEBUG */ ! if ((error = tsleep((caddr_t)lock, priority, lockstr, 0))) { ! /* ! * We may have been awakened by a signal (in ! * which case we must remove ourselves from the ! * blocked list) and/or by another process ! * releasing a lock (in which case we have already ! * been removed from the blocked list and our ! * lf_next field set to NOLOCKF). ! */ ! if (lock->lf_next) ! TAILQ_REMOVE(&lock->lf_next->lf_blkhd, lock, ! lf_block); ! free(lock, M_LOCKF); ! return (error); } } --- 273,292 ---- } #endif /* LOCKF_DEBUG */ ! error = tsleep((caddr_t)lock, priority, lockstr, 0); ! /* ! * We may have been awakened by a signal and/or by a ! * debugger continuing us (in which cases we must remove ! * ourselves from the blocked list) and/or by another ! * process releasing a lock (in which case we have ! * already been removed from the blocked list and our ! * lf_next field set to NOLOCKF). ! */ ! if (lock->lf_next) { ! TAILQ_REMOVE(&lock->lf_next->lf_blkhd, lock, lf_block); ! lock->lf_next = NOLOCKF; ! } ! if (error) { ! free(lock, M_LOCKF); ! return (error); } } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message