- p = g;
- do {
- if (p->mm) {
- if (p->mm == mm) {
- /*
- * p->sighand can't disappear, but
- * may be changed by de_thread()
- */
- lock_task_sighand(p, &flags);
- zap_process(p);
- unlock_task_sighand(p, &flags);
- }
- break;
+ if (unlikely(traced)) {
+ /*
+ * We are zapping a thread and the thread it ptraces.
+ * If the tracee went into a ptrace stop for exit tracing,
+ * we could deadlock since the tracer is waiting for this
+ * coredump to finish. Detach them so they can both die.
+ */
+ write_lock_irq(&tasklist_lock);
+ do_each_thread(g,p) {
+ if (mm == p->mm && p != tsk &&
+ p->ptrace && p->parent->mm == mm) {
+ __ptrace_detach(p, 0);