Commit b9daa006 authored by Ingo Molnar's avatar Ingo Molnar

[PATCH] threaded coredumps, tcore-fixes-2.5.51-A0

This fixes one more threaded-coredumps detail reported by the glibc
people: all threads taken down by the coredump code should report the
proper exit code.  We can do this rather easily via the group_exit
mechanism.  'Other' threads used to report SIGKILL, which was highly
confusing as the shell often displayed the 'Killed' message instead of a
'Segmentation fault' message.

Another missing bit was the 0x80 bit set in the exit status for all
threads, if the coredump was successful.  (it's safe to set this bit in
->sig->group_exit_code in an unlocked way because all threads are
artificially descheduled by the coredump code.)
parent f3ce0064
...@@ -1268,7 +1268,7 @@ static void coredump_wait(struct mm_struct *mm) ...@@ -1268,7 +1268,7 @@ static void coredump_wait(struct mm_struct *mm)
BUG_ON(mm->core_waiters); BUG_ON(mm->core_waiters);
} }
int do_coredump(long signr, struct pt_regs * regs) int do_coredump(long signr, int exit_code, struct pt_regs * regs)
{ {
char corename[CORENAME_MAX_SIZE + 1]; char corename[CORENAME_MAX_SIZE + 1];
struct mm_struct *mm = current->mm; struct mm_struct *mm = current->mm;
...@@ -1288,6 +1288,8 @@ int do_coredump(long signr, struct pt_regs * regs) ...@@ -1288,6 +1288,8 @@ int do_coredump(long signr, struct pt_regs * regs)
} }
mm->dumpable = 0; mm->dumpable = 0;
init_completion(&mm->core_done); init_completion(&mm->core_done);
current->sig->group_exit = 1;
current->sig->group_exit_code = exit_code;
coredump_wait(mm); coredump_wait(mm);
if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump) if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
...@@ -1314,6 +1316,7 @@ int do_coredump(long signr, struct pt_regs * regs) ...@@ -1314,6 +1316,7 @@ int do_coredump(long signr, struct pt_regs * regs)
retval = binfmt->core_dump(signr, regs, file); retval = binfmt->core_dump(signr, regs, file);
current->sig->group_exit_code |= 0x80;
close_fail: close_fail:
filp_close(file, NULL); filp_close(file, NULL);
fail_unlock: fail_unlock:
......
...@@ -57,7 +57,7 @@ extern int setup_arg_pages(struct linux_binprm * bprm); ...@@ -57,7 +57,7 @@ extern int setup_arg_pages(struct linux_binprm * bprm);
extern int copy_strings(int argc,char ** argv,struct linux_binprm *bprm); extern int copy_strings(int argc,char ** argv,struct linux_binprm *bprm);
extern int copy_strings_kernel(int argc,char ** argv,struct linux_binprm *bprm); extern int copy_strings_kernel(int argc,char ** argv,struct linux_binprm *bprm);
extern void compute_creds(struct linux_binprm *binprm); extern void compute_creds(struct linux_binprm *binprm);
extern int do_coredump(long signr, struct pt_regs * regs); extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
extern void set_binfmt(struct linux_binfmt *new); extern void set_binfmt(struct linux_binfmt *new);
......
...@@ -1313,7 +1313,7 @@ int get_signal_to_deliver(siginfo_t *info, struct pt_regs *regs) ...@@ -1313,7 +1313,7 @@ int get_signal_to_deliver(siginfo_t *info, struct pt_regs *regs)
case SIGQUIT: case SIGILL: case SIGTRAP: case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV: case SIGABRT: case SIGFPE: case SIGSEGV:
case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ: case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, regs)) if (do_coredump(signr, exit_code, regs))
exit_code |= 0x80; exit_code |= 0x80;
/* FALLTHRU */ /* FALLTHRU */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment