small multi-threaded coredump patch

cvarner@corp.spinway.com
Wed, 3 Nov 1999 12:57:22 -0800


Hello,

Here is a short patch to coredump a segfaulting thread in a
linux-threads program. Rather than dumping to core.pid() or other
more complicated scheme, I added a flag to the mm_struct to mark
whether the corefile has been generated. The patch assumes that the
process/thread which caused the segfault will be the first to dump.
I've done some testing on single and dual cpu boxes, and this always
seems to work.

As the patch is really short, here it is. My changes were made (and
tested with) the 2.3.18 kernel, but the patch will also apply against
the most recent kernel(2.3.25).

diff -u --recursive -b -B linux-old/linux/fs/exec.c linux/fs/exec.c
--- linux-old/linux/fs/exec.c Tue Sep 7 10:57:20 1999
+++ linux/fs/exec.c Tue Nov 2 15:57:40 1999
@@ -801,7 +801,6 @@
int do_coredump(long signr, struct pt_regs * regs)
{
struct linux_binfmt * binfmt;
- char corename[6+sizeof(current->comm)];
struct file * file;
struct dentry * dentry;
struct inode * inode;
@@ -810,19 +809,17 @@
binfmt = current->binfmt;
if (!binfmt || !binfmt->core_dump)
goto fail;
- if (!current->dumpable || atomic_read(&current->mm->mm_users) != 1)
+
+ if (!current->dumpable || atomic_read(&current->mm->already_dumped) == 1)
goto fail;
+
current->dumpable = 0;
+ atomic_set(&current->mm->already_dumped, 1);
+
if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
goto fail;

- memcpy(corename,"core.", 5);
-#if 0
- memcpy(corename+5,current->comm,sizeof(current->comm));
-#else
- corename[4] = '\0';
-#endif
- file = filp_open(corename, O_CREAT | 2 | O_TRUNC | O_NOFOLLOW, 0600);
+ file = filp_open("core", O_CREAT | 2 | O_TRUNC | O_NOFOLLOW, 0600);
if (IS_ERR(file))
goto fail;
dentry = file->f_dentry;
diff -u --recursive -b -B linux-old/linux/include/linux/sched.h linux/include/linux/sched.h
--- linux-old/linux/include/linux/sched.h Thu Sep 9 22:17:31 1999
+++ linux/include/linux/sched.h Tue Nov 2 16:01:25 1999
@@ -221,6 +221,8 @@
unsigned long cpu_vm_mask;
unsigned long swap_cnt; /* number of pages to swap on next pass */
unsigned long swap_address;
+ atomic_t already_dumped;
+
/*
* This is an architecture-specific pointer: the portable
* part of Linux does not know about any segments.
@@ -239,7 +241,7 @@
0, 0, 0, \
0, 0, 0, 0, \
0, 0, 0, \
- 0, 0, 0, 0, NULL }
+ 0, 0, 0, 0, ATOMIC_INIT(0), NULL }

struct signal_struct {
atomic_t count;

-- 

Curtis Varner / Lead Software Engineer cvarner@corp.spinway.com Spinway.com(tm) (1-877-SPINWAY) 1-650-207-0732

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/