[PATCH] Coredumping threads.

From: Terje Malmedal (tm@funcom.com)
Date: Sun May 21 2000 - 13:22:58 EST


Under linux multi-threaded applications do not dump core when they get
an segmentation fault. This makes debugging such applications
difficult.

This patch adds a new sysctl /proc/sys/kernel/coredumptype which when
enabled(it is off by default in order not to surprise people) makes
all threads in an application dump core simultaneously to separate
files named core.<processname>.<pid>.

I've found this very useful. If there is general interest for this I
can make a version for 2.3 and submit it for inclusion in the standard
kernel.

diff -ur linux-2.2.15/fs/binfmt_elf.c linux/fs/binfmt_elf.c
--- linux-2.2.15/fs/binfmt_elf.c Thu May 4 02:16:46 2000
+++ linux/fs/binfmt_elf.c Fri May 19 16:42:56 2000
@@ -1058,6 +1058,40 @@
 #define DUMP_SEEK(off) \
         if (!dump_seek(file, (off))) \
                 goto close_coredump;
+
+static int elf_core_dump2(long signr, struct pt_regs * regs);
+void force_sig(int sig, struct task_struct *p);
+
+int coredumptype = 0; /* Meaning: 0 normal core file.
+ 1 dump all threads to core.processname.pid
+ */
+/* First make current process dump core as normal, then we hunt down
+ all threads which share the same memory map and force them to
+ core as well
+
+ Terje Malmedal <tm@funcom.com>
+*/
+
+static int elf_core_dump(long signr, struct pt_regs * regs)
+{
+ struct task_struct *tsk = current->next_task;
+ int ret = 0;
+ ret = elf_core_dump2(signr,regs);
+ if(coredumptype == 1) {
+ while(tsk && tsk != current) {
+ if(current->mm->mmap == tsk->mm->mmap) {
+#ifdef DEBUG
+ printk("Forcing SEGV to %d (%s)\n",
+ tsk->pid,tsk->comm);
+#endif
+ force_sig(SIGSEGV,tsk);
+ }
+ tsk = tsk->next_task;
+ }
+ }
+ return ret;
+}
+
 /*
  * Actual dumper
  *
@@ -1065,14 +1099,17 @@
  * and then they are actually written out. If we run out of core limit
  * we just truncate.
  */
-static int elf_core_dump(long signr, struct pt_regs * regs)
+static int elf_core_dump2(long signr, struct pt_regs * regs)
 {
         int has_dumped = 0;
         struct file *file;
         struct dentry *dentry;
         struct inode *inode;
         mm_segment_t fs;
- char corefile[6+sizeof(current->comm)];
+ char corefile[sizeof(current->comm)+16]; /* room for "core." +
+ current->comm +
+ pid(10 digits) +
+ '\0' */
         int segs;
         int i;
         size_t size;
@@ -1088,7 +1125,7 @@
 
         if (!current->dumpable ||
             limit < ELF_EXEC_PAGESIZE ||
- atomic_read(&current->mm->count) != 1)
+ atomic_read(&current->mm->count) < 1)
                 return 0;
         current->dumpable = 0;
 
@@ -1140,12 +1177,14 @@
         fs = get_fs();
         set_fs(KERNEL_DS);
 
- memcpy(corefile,"core.",5);
-#if 0
- memcpy(corefile+5,current->comm,sizeof(current->comm));
-#else
- corefile[4] = '\0';
-#endif
+ if(coredumptype == 1) {
+ sprintf(corefile,"core.%s.%d",
+ current->comm,
+ current->pid);
+ } else {
+ sprintf(corefile,"core");
+ }
+
         file = filp_open(corefile, O_CREAT | 2 | O_TRUNC | O_NOFOLLOW, 0600);
         if (IS_ERR(file))
                 goto end_coredump;
diff -ur linux-2.2.15/include/linux/sysctl.h linux/include/linux/sysctl.h
--- linux-2.2.15/include/linux/sysctl.h Thu May 4 02:16:52 2000
+++ linux/include/linux/sysctl.h Fri May 19 16:53:15 2000
@@ -81,7 +81,7 @@
         KERN_CAP_BSET=14, /* int: capability bounding set */
         KERN_PANIC=15, /* int: panic timeout */
         KERN_REALROOTDEV=16, /* real root device to mount after initrd */
-
+ KERN_COREDUMPTYPE=17, /* what kind of coredumps do we wish to do */
         KERN_JAVA_INTERPRETER=19, /* path to Java(tm) interpreter */
         KERN_JAVA_APPLETVIEWER=20, /* path to Java(tm) appletviewer */
         KERN_SPARC_REBOOT=21, /* reboot command on Sparc */
diff -ur linux-2.2.15/kernel/sysctl.c linux/kernel/sysctl.c
--- linux-2.2.15/kernel/sysctl.c Thu May 4 02:16:53 2000
+++ linux/kernel/sysctl.c Fri May 19 16:44:39 2000
@@ -33,6 +33,7 @@
 
 /* External variables not in a header file. */
 extern int panic_timeout;
+extern int coredumptype;
 extern int console_loglevel, C_A_D;
 extern int bdf_prm[], bdflush_min[], bdflush_max[];
 extern char binfmt_java_interpreter[], binfmt_java_appletviewer[];
@@ -169,6 +170,8 @@
         {KERN_DOMAINNAME, "domainname", system_utsname.domainname, 64,
          0644, NULL, &proc_doutsstring, &sysctl_string},
         {KERN_PANIC, "panic", &panic_timeout, sizeof(int),
+ 0644, NULL, &proc_dointvec},
+ {KERN_COREDUMPTYPE, "coredumptype" , &coredumptype,sizeof(int),
          0644, NULL, &proc_dointvec},
 #ifdef CONFIG_PROC_FS
         {KERN_CAP_BSET, "cap-bound", &cap_bset, sizeof(kernel_cap_t),

-- 
 - Terje
tm@funcom.com

- 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/



This archive was generated by hypermail 2b29 : Tue May 23 2000 - 21:00:20 EST