Date: Thu, 17 Jun 1999 13:10:02 -0700 (PDT) From: Bruce Evans <bde@zeta.org.au> To: freebsd-bugs@FreeBSD.org Subject: Re: kern/12247: userlevel program let kernel hang Message-ID: <199906172010.NAA86851@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/12247; it has been noted by GNATS. From: Bruce Evans <bde@zeta.org.au> 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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199906172010.NAA86851>