From 13e165baf6ada9f427c319bd41a1c7a9c7b4f0a6 Mon Sep 17 00:00:00 2001 From: Paul Pluzhnikov Date: Tue, 22 Mar 2011 16:33:46 -0700 Subject: [PATCH] uml: kernels on {i386,x86_64} produce bad coredumps One of our users reported that when a user-level program SIGSEGVs under UML kernel, the resulting core dump is not very usable. I have reproduced that with the latest kernel: make ARCH=um defconfig; make ARCH=um Run the resulting kernel, then "inside" run this program: #include void *fn(void *p) { abort(); } int main() { pthread_t tid; pthread_create(&tid, 0, fn, 0); pthread_join(tid, 0); return 0; } Analyze the coredump with GDB. Here is what you'll see: sudo gdb -q -ex 'set solib-absolute-prefix ../root_fs' -ex 'file ../root_fs/var/tmp/mt-abort' -ex 'core ../root_fs/var/tmp/core.762' Reading symbols from /usr/local/google/root_fs/var/tmp/mt-abort...done. [New Thread 763] [New Thread 762] Core was generated by `./mt-abort'. Program terminated with signal 6, Aborted. #0 0x0000000040255250 in raise () from ../root_fs/lib64/libc.so.6 (gdb) info thread 2 Thread 762 0x0000000000000000 in ?? () * 1 Thread 763 0x0000000040255250 in raise () from ../root_fs/lib64/libc.so.6 Note that thread#2 looks funny. (gdb) thread 2 [Switching to thread 2 (Thread 762)]#0 0x0000000000000000 in ?? () (gdb) info reg rax 0x0 0 rbx 0x0 0 rcx 0x0 0 rdx 0x0 0 rsi 0x0 0 rdi 0x0 0 rbp 0x0 0x0 rsp 0x0 0x0 r8 0x0 0 r9 0x0 0 r10 0x0 0 r11 0x0 0 r12 0x0 0 r13 0x0 0 r14 0x0 0 r15 0x0 0 rip 0x0 0 eflags 0x0 [ ] cs 0x0 0 ss 0x0 0 ds 0x0 0 es 0x0 0 fs 0x0 0 gs 0x0 0 Examining the core shows that NT_PRSTATUS notes for all threads other than the one that crashed are zeroed out. I believe this is happening because neither ELF_CORE_COPY_TASK_REGS nor task_pt_regs are defined under ARCH=um, and so elf_core_copy_task_regs() becomes a no-op. Attached patch fixes this for SUBARCH={x86_64,i386}. Signed-off-by: Paul Pluzhnikov Cc: Jeff Dike Acked-by: WANG Cong Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/sys-i386/asm/elf.h | 2 ++ arch/um/sys-x86_64/asm/elf.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/arch/um/sys-i386/asm/elf.h b/arch/um/sys-i386/asm/elf.h index a979a22a8d9f..d964a4111ac6 100644 --- a/arch/um/sys-i386/asm/elf.h +++ b/arch/um/sys-i386/asm/elf.h @@ -75,6 +75,8 @@ typedef struct user_i387_struct elf_fpregset_t; pr_reg[16] = PT_REGS_SS(regs); \ } while (0); +#define task_pt_regs(t) (&(t)->thread.regs) + struct task_struct; extern int elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu); diff --git a/arch/um/sys-x86_64/asm/elf.h b/arch/um/sys-x86_64/asm/elf.h index d760967f33a7..d6d5af376251 100644 --- a/arch/um/sys-x86_64/asm/elf.h +++ b/arch/um/sys-x86_64/asm/elf.h @@ -95,6 +95,8 @@ typedef struct user_i387_struct elf_fpregset_t; (pr_reg)[25] = 0; \ (pr_reg)[26] = 0; +#define task_pt_regs(t) (&(t)->thread.regs) + struct task_struct; extern int elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu);