Multi-threaded core dumps for 2.4.18 non-O(1) kernels.
Subsystems (3)
PATCH 1/1 Multi-threaded core dumps for 2.4.18 non-O(1) kernels.
The following patch is a back port of the 2.5.18 tcore patch I posted last week.
It applies cleanly to the 2.4.18-ia64 tree.
The ia64 SMP version has been tested and works very well.
To use this patch you will need to strip the objects from the libpthread module loaded by GDB at post mortem debug time.
('strip /lib/libpthread-0.9.so for my system', YMMV)
--mgross
arch/i386/kernel/i387.c +41 -0
@@ -520,3 +520,44 @@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; +} + + +#ifdef CONFIG_SMP +void dump_smp_unlazy_fpu (void ) +{ +unlazy_fpu (current); +return ; +} +#endif +
arch/i386/kernel/process.c +18 -0
@@ -644,6 +644,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_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 +58 -14
105 lines not on this page · raw message
fs/binfmt_elf.c +250 -90
417 lines not on this page · raw message
include/asm-i386/elf.h +15 -0
@@ -99,6 +99,21 @@#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) + +#ifdef CONFIG_SMP +extern void dump_smp_unlazy_fpu (void ); +#define ELF_CORE_SYNC dump_smp_unlazy_fpu +#endif +#endif #endif
include/asm-ia64/elf.h +10 -0
@@ -66,12 +66,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);
@@ -89,6 +93,12 @@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 +3 -1
@@ -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 {
@@ -607,5 +610,4 @@#endif -#endif /* _LINUX_ELF_H */
include/linux/elfcore.h +62 -0
66 lines not on this page · raw message
include/linux/sched.h +8 -0
@@ -132,6 +132,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 +105 -1
124 lines not on this page · raw message