Skip to contentSkip to conversation

Multithreaded core dump for ia64 and i386 architectures

PATCH New mgross 1 participant 1 message Jun 6, 2002

Subsystems (3)
lore
Share & tools
lore

mgross

author
#0 lore raw

PATCH 1/1 Multithreaded core dump for ia64 and i386 architectures

This is a version of the tcore multi-threaded core dump patch that supports both i386 and ia64 architectures.

Its been smoke tested on a 2 way Itanium system as well as a 2 way P4 system. So far its been very stable on both architectures

This patch applies cleanly to the 2.5.18 kernel.

This multithread core dump differs from my earlier patches in that this patch works with ia64 kernels, when applied after the Mosberger ia64 port patch. There is only 2 off by 6 line warnings, in ia64/kernel/process.c, when this patch is applied to the ia64 kernel. This is due to the ia64 port patch adding some lines to that file.

This patch also differs from the earlier patches in that I've removed the proc interface to enable / disable the multi-threaded core file creation. This is no longer needed as t he patch is holding up as stable, and its inconvenient to have to enable the feature that could "just work".

Apply this patch then when a multi-threaded application dumps core, it will create a core file with the data for all the processes in the thread group. BTW, non-threaded applications still produce good core files ;)

This code works by "suspending" the other thread group processes, and then adding extra note sections to the core file with the user register state data. GDB 5.x knows how to work with these core files with one caveat. You may need to "strip libpthread*" before loading up the core file and crashing application into gdb. GDB 5.x; x < 2, seems to have a problem loading symbols for libpthread in this type of use.

The process suspend design does a number of interesting things that are worth pointing out... again ;)
1) it creates an extra run queue that has no cpu, the phantom cpu.
2) it uses process migration to migrate the processes of the thread group to the phantom run queue.
3) it removes the down_write from elf_dump_core, to avoid any possibility of deadlocking with one of the suspended thread processes. This is safe to do as the other thread process are suspended and cannot free pages while they aren't getting any CPU time.

I will be making one more re-base of this patch for whatever the current 2.5.x is next week, after I finish the 2.4.x version. I think it would be a good thing for this patch / feature make it into the kernel, especially a development one.

--mgross

arch/i386/kernel/i387.c Thu Jun 6 15:51:09 2002 renamed from linux-2.5.18/arch/i386/kernel/i387.c Fri May 24 21:55:31 2002 +33 -0
diff -urN -X dontdiff src/linux-2.5.18/arch/i386/kernel/i387.c linux2518/arch/i386/kernel/i387.c
@@ -528,3 +528,36 @@
 
        return fpvalid;
 }
+
+int dump_task_fpu( struct task_struct *tsk, struct user_i387_struct *fpu )
+{
+       int fpvalid;
+
+       fpvalid = tsk->used_math;
+       if ( fpvalid ) {
+               if (tsk = current) unlazy_fpu( tsk );
+               if ( cpu_has_fxsr ) {
+                       copy_fpu_fxsave( tsk, fpu );
+               } else {
+                       copy_fpu_fsave( tsk, fpu );
+               }
+       }
+
+       return fpvalid;
+}
+
+int dump_task_extended_fpu( struct task_struct *tsk, struct user_fxsr_struct *fpu )
+{
+       int fpvalid;
+
+       fpvalid = tsk->used_math && cpu_has_fxsr;
+       if ( fpvalid ) {
+               if (tsk = current) unlazy_fpu( tsk );
+               memcpy( fpu, &tsk->thread.i387.fxsave,
+               sizeof(struct user_fxsr_struct) );
+       }
+
+       return fpvalid;
+}
+
+
arch/i386/kernel/process.c Thu Jun 6 15:51:09 2002 renamed from linux-2.5.18/arch/i386/kernel/process.c Fri May 24 21:55:16 2002 +18 -0
diff -urN -X dontdiff src/linux-2.5.18/arch/i386/kernel/process.c linux2518/arch/i386/kernel/process.c
@@ -610,6 +610,24 @@
 
        dump->u_fpvalid = dump_fpu (regs, &dump->i387);
 }
+/*
+ * Capture the user space registers if the task is not running (in user space)
+ */
+#include <linux/elfcore.h>
+int dump_task_regs(struct task_struct *tsk,  elf_gregset_t *regs)
+{
+       struct pt_regs ptregs;
+
+       ptregs = *(struct pt_regs *)((unsigned long)tsk->thread_info + THREAD_SIZE - sizeof(struct pt_regs));
+       ptregs.xcs &= 0xffff;
+       ptregs.xds &= 0xffff;
+       ptregs.xes &= 0xffff;
+       ptregs.xss &= 0xffff;
+
+       elf_core_copy_regs(regs, &ptregs);
+
+       return 1;
+}
 
 /*
  * This special macro can be used to load a debugging register
arch/ia64/kernel/process.c Thu Jun 6 15:51:09 2002 renamed from linux-2.5.18/arch/ia64/kernel/process.c Fri May 24 21:55:26 2002 +58 -14

105 lines not on this page · raw message

fs/binfmt_elf.c Thu Jun 6 15:51:09 2002 renamed from linux-2.5.18/fs/binfmt_elf.c Fri May 24 21:55:26 2002 +252 -90

432 lines not on this page · raw message

include/asm-i386/elf.h Thu Jun 6 15:56:51 2002 renamed from linux-2.5.18/include/asm-i386/elf.h Fri May 24 21:55:29 2002 +10 -0
diff -urN -X dontdiff src/linux-2.5.18/include/asm-i386/elf.h linux2518/include/asm-i386/elf.h
@@ -99,6 +99,16 @@
 
 #ifdef __KERNEL__
 #define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+
+
+extern int dump_task_regs (struct task_struct *, elf_gregset_t *);
+extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
+extern int dump_task_extended_fpu (struct task_struct *, struct user_fxsr_struct *);
+
+#define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs)
+#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
+#define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) dump_task_extended_fpu(tsk, elf_xfpregs)
+
 #endif
 
 #endif
include/asm-ia64/elf.h Thu Jun 6 15:51:09 2002 renamed from linux-2.5.18/include/asm-ia64/elf.h Fri May 24 21:55:29 2002 +12 -0
diff -urN -X dontdiff src/linux-2.5.18/include/asm-ia64/elf.h linux2518/include/asm-ia64/elf.h
@@ -65,12 +65,16 @@
 #define ELF_NGREG      128     /* we really need just 72 but let's leave some headroom... */
 #define ELF_NFPREG     128     /* f0 and f1 could be omitted, but so what... */
 
+typedef unsigned long elf_fpxregset_t;
+
 typedef unsigned long elf_greg_t;
 typedef elf_greg_t elf_gregset_t[ELF_NGREG];
 
 typedef struct ia64_fpreg elf_fpreg_t;
 typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
 
+
+
 struct pt_regs;        /* forward declaration... */
 extern void ia64_elf_core_copy_regs (struct pt_regs *src, elf_gregset_t dst);
 #define ELF_CORE_COPY_REGS(_dest,_regs)        ia64_elf_core_copy_regs(_regs, _dest);
@@ -88,6 +92,14 @@
 struct elf64_hdr;
 extern void ia64_set_personality (struct elf64_hdr *elf_ex, int ibcs2_interpreter);
 #define SET_PERSONALITY(ex, ibcs2)     ia64_set_personality(&(ex), ibcs2)
+
+extern int dump_task_regs(struct task_struct *, elf_gregset_t *);
+extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
+
+#define ELF_CORE_COPY_TASK_REGS(tsk, elf_gregs) dump_task_regs(tsk, elf_gregs)
+#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
+
+
 #endif
 
 #endif /* _ASM_IA64_ELF_H */
include/linux/elf.h Thu Jun 6 15:57:37 2002 renamed from linux-2.5.18/include/linux/elf.h Fri May 24 21:55:20 2002 +3 -1
diff -urN -X dontdiff src/linux-2.5.18/include/linux/elf.h linux2518/include/linux/elf.h
@@ -576,6 +576,9 @@
 #define NT_PRPSINFO    3
 #define NT_TASKSTRUCT  4
 #define NT_PRFPXREG    20
+#define NT_PRXFPREG     0x46e62b7f     /* note name must be "LINUX" as per GDB */
+                                       /* from gdb5.1/include/elf/common.h */
+
 
 /* Note header in a PT_NOTE section */
 typedef struct elf32_note {
@@ -606,6 +609,5 @@
 #define elf_note       elf64_note
 
 #endif
-
 
 #endif /* _LINUX_ELF_H */
include/linux/elfcore.h Thu Jun 6 15:57:37 2002 renamed from linux-2.5.18/include/linux/elfcore.h Fri May 24 21:55:26 2002 +44 -0

48 lines not on this page · raw message

include/linux/sched.h Thu Jun 6 15:55:30 2002 renamed from linux-2.5.18/include/linux/sched.h Fri May 24 21:55:19 2002 +8 -0
diff -urN -X dontdiff src/linux-2.5.18/include/linux/sched.h linux2518/include/linux/sched.h
@@ -131,6 +131,14 @@
 
 #include <linux/spinlock.h>
 
+
+/* functions for pausing and resumming functions
+ * common mm's without using signals.  These are used
+ * by the multithreaded elf core dump code in binfmt_elf.c*/
+extern void tcore_suspend_threads( void );
+extern void tcore_resume_threads( void );
+
+
 /*
  * This serializes "schedule()" and also protects
  * the run-queue from deletions/modifications (but
kernel/sched.c Thu Jun 6 15:51:09 2002 renamed from linux-2.5.18/kernel/sched.c Fri May 24 21:55:22 2002 +169 -9

228 lines not on this page · raw message