From: Kirill Korotaev Note, that during exit process there can be a thread in the system with tsk->sighand == NULL, since the following call trace: release_task() { .... __exit_sighand() <<< makes tsk->sighand == NULL; __unhash_process() <<< unhashes thread .... } next, we see that next_thread checks for tsk->sighand != NULL: task_t fastcall *next_thread(const task_t *p) { #ifdef CONFIG_SMP if (!p->sighand) BUG(); <<< BUG happened here!!! if (!spin_is_locked(&p->sighand->siglock) && !rwlock_is_locked(&tasklist_lock)) .... } So the question is why next_thread() should check for (p->sighand != NULL) && spin_is_locked(&p->sighand->siglock)? I think these checks are invalid. For example do_task_stat() (which called next_thread() in this BUG) checks for tsk->sighand != NULL explicitly. And moreover, next_thread() DOES always works correctly, whether there are threads or none. This patch removes sighand checks from the next_thread(), since they are incorrect and has nothing to do with the next_thread() function. So they could trigger BUG() when there were no actually bug at all. Signed-Off-By: Kirill Korotaev Signed-off-by: Andrew Morton --- 25-akpm/kernel/exit.c | 5 +---- 1 files changed, 1 insertion(+), 4 deletions(-) diff -puN kernel/exit.c~next_thread-bug-fixes kernel/exit.c --- 25/kernel/exit.c~next_thread-bug-fixes 2004-09-13 01:01:22.227228320 -0700 +++ 25-akpm/kernel/exit.c 2004-09-13 01:01:22.231227712 -0700 @@ -857,10 +857,7 @@ asmlinkage long sys_exit(int error_code) task_t fastcall *next_thread(const task_t *p) { #ifdef CONFIG_SMP - if (!p->sighand) - BUG(); - if (!spin_is_locked(&p->sighand->siglock) && - !rwlock_is_locked(&tasklist_lock)) + if (!rwlock_is_locked(&tasklist_lock)) BUG(); #endif return pid_task(p->pids[PIDTYPE_TGID].pid_list.next, PIDTYPE_TGID); _