Commit 8f0af4f8 authored by Cyrill Gorcunov's avatar Cyrill Gorcunov

Restore task's command line as well

Note binary format for core file is changed.
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@gmail.com>
parent a00ef142
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <sys/ptrace.h> #include <sys/ptrace.h>
#include <sys/user.h> #include <sys/user.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/prctl.h>
#include <sys/sendfile.h> #include <sys/sendfile.h>
...@@ -404,6 +405,40 @@ err: ...@@ -404,6 +405,40 @@ err:
#define assign_reg(dst, src, e) dst.e = (__typeof__(dst.e))src.e #define assign_reg(dst, src, e) dst.e = (__typeof__(dst.e))src.e
#define assign_array(dst, src, e) memcpy(&dst.e, &src.e, sizeof(dst.e)) #define assign_array(dst, src, e) memcpy(&dst.e, &src.e, sizeof(dst.e))
static int get_task_comm(pid_t pid, u8 *comm)
{
FILE *file = NULL;
char *tok1, *tok2;
int ret = -1;
snprintf(loc_buf, sizeof(loc_buf), "/proc/%d/stat", pid);
file = fopen(loc_buf, "r");
if (!file) {
pr_perror("Can't open %s", loc_buf);
goto err;
}
if (!fgets(loc_buf, sizeof(loc_buf), file)) {
perror("Can't read task stat");
goto err;
}
tok1 = strtok(loc_buf, "(");
tok2 = strtok(NULL, ")");
if ((long)tok1 & (long)tok2) {
strncpy((char *)comm, tok2, TASK_COMM_LEN);
ret = 0;
} else {
printf("Unable to parse task stat\n");
ret = -1;
}
err:
if (file)
fclose(file);
return ret;
}
static int get_task_personality(pid_t pid, u32 *personality) static int get_task_personality(pid_t pid, u32 *personality)
{ {
FILE *file = NULL; FILE *file = NULL;
...@@ -558,6 +593,12 @@ static int dump_task_core_seized(pid_t pid, struct cr_fdset *cr_fdset) ...@@ -558,6 +593,12 @@ static int dump_task_core_seized(pid_t pid, struct cr_fdset *cr_fdset)
goto err_free; goto err_free;
pr_info("OK\n"); pr_info("OK\n");
pr_info("Obtainting task command ... ");
ret = get_task_comm(pid, core->comm);
if (ret)
goto err_free;
pr_info("OK\n");
pr_info("Dumping header ... "); pr_info("Dumping header ... ");
core->hdr.version = HEADER_VERSION; core->hdr.version = HEADER_VERSION;
core->hdr.arch = HEADER_ARCH_X86_64; core->hdr.arch = HEADER_ARCH_X86_64;
......
...@@ -65,7 +65,7 @@ static void free_pstree(void) ...@@ -65,7 +65,7 @@ static void free_pstree(void)
INIT_LIST_HEAD(&pstree_list); INIT_LIST_HEAD(&pstree_list);
} }
static void show_regs(struct cr_fdset *cr_fdset) static void show_core_regs(struct cr_fdset *cr_fdset)
{ {
struct user_regs_entry regs; struct user_regs_entry regs;
struct desc_struct tls; struct desc_struct tls;
...@@ -102,6 +102,28 @@ err: ...@@ -102,6 +102,28 @@ err:
return; return;
} }
static void show_core_rest(struct cr_fdset *cr_fdset)
{
int fd_core, i;
u32 personality;
char comm[TASK_COMM_LEN];
fd_core = cr_fdset->desc[CR_FD_CORE].fd;
if (fd_core < 0)
goto err;
lseek(fd_core, GET_FILE_OFF(struct core_entry, personality), SEEK_SET);
read_ptr_safe(fd_core, &personality, err);
lseek(fd_core, GET_FILE_OFF(struct core_entry, comm), SEEK_SET);
read_safe(fd_core, comm, TASK_COMM_LEN, err);
pr_info("Personality: %x\n", personality);
pr_info("Command: %s\n", comm);
err:
return;
}
static void show_files(struct cr_fdset *cr_fdset) static void show_files(struct cr_fdset *cr_fdset)
{ {
struct fdinfo_entry e; struct fdinfo_entry e;
...@@ -188,7 +210,8 @@ static void show_core(struct cr_fdset *cr_fdset) ...@@ -188,7 +210,8 @@ static void show_core(struct cr_fdset *cr_fdset)
if (fd_core < 0) if (fd_core < 0)
goto out; goto out;
show_regs(cr_fdset); show_core_regs(cr_fdset);
show_core_rest(cr_fdset);
lseek(fd_core, GET_FILE_OFF_AFTER(struct core_entry), SEEK_SET); lseek(fd_core, GET_FILE_OFF_AFTER(struct core_entry), SEEK_SET);
......
...@@ -137,18 +137,8 @@ struct user_regs_entry { ...@@ -137,18 +137,8 @@ struct user_regs_entry {
} __packed; } __packed;
struct desc_struct { struct desc_struct {
union { u32 a;
struct { u32 b;
u32 a;
u32 b;
};
struct {
u16 limit0;
u16 base0;
unsigned base1: 8, type: 4, s: 1, dpl: 2, p: 1;
unsigned limit: 4, avl: 1, l: 1, d: 1, g: 1, base2: 8;
};
};
} __packed; } __packed;
struct user_fpregs_entry { struct user_fpregs_entry {
...@@ -167,6 +157,7 @@ struct user_fpregs_entry { ...@@ -167,6 +157,7 @@ struct user_fpregs_entry {
} __packed; } __packed;
#define GDT_ENTRY_TLS_ENTRIES 3 #define GDT_ENTRY_TLS_ENTRIES 3
#define TASK_COMM_LEN 16
struct core_entry { struct core_entry {
struct image_header hdr; struct image_header hdr;
...@@ -174,6 +165,7 @@ struct core_entry { ...@@ -174,6 +165,7 @@ struct core_entry {
struct user_fpregs_entry fpregs; struct user_fpregs_entry fpregs;
struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES]; struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
u32 personality; u32 personality;
u8 comm[TASK_COMM_LEN];
} __packed; } __packed;
#endif /* CONFIG_X86_64 */ #endif /* CONFIG_X86_64 */
......
...@@ -18,9 +18,9 @@ Signed-off-by: Andrew Vagin <avagin@openvz.org> ...@@ -18,9 +18,9 @@ Signed-off-by: Andrew Vagin <avagin@openvz.org>
--- ---
arch/x86/include/asm/elf.h | 3 arch/x86/include/asm/elf.h | 3
arch/x86/vdso/vma.c | 22 ++ arch/x86/vdso/vma.c | 22 ++
fs/binfmt_elf.c | 402 ++++++++++++++++++++++++++++++++++++++++++++- fs/binfmt_elf.c | 405 ++++++++++++++++++++++++++++++++++++++++++++-
include/linux/elf_ckpt.h | 135 +++++++++++++++ include/linux/elf_ckpt.h | 127 ++++++++++++++
4 files changed, 560 insertions(+), 2 deletions(-) 4 files changed, 555 insertions(+), 2 deletions(-)
Index: linux-2.6.git/arch/x86/include/asm/elf.h Index: linux-2.6.git/arch/x86/include/asm/elf.h
=================================================================== ===================================================================
...@@ -88,7 +88,7 @@ Index: linux-2.6.git/fs/binfmt_elf.c ...@@ -88,7 +88,7 @@ Index: linux-2.6.git/fs/binfmt_elf.c
static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
static int load_elf_library(struct file *); static int load_elf_library(struct file *);
@@ -556,6 +564,390 @@ static unsigned long randomize_stack_top @@ -556,6 +564,393 @@ static unsigned long randomize_stack_top
#endif #endif
} }
...@@ -120,6 +120,7 @@ Index: linux-2.6.git/fs/binfmt_elf.c ...@@ -120,6 +120,7 @@ Index: linux-2.6.git/fs/binfmt_elf.c
+ int cpu; + int cpu;
+ +
+ BUILD_BUG_ON(CKPT_GDT_ENTRY_TLS_ENTRIES != GDT_ENTRY_TLS_ENTRIES); + BUILD_BUG_ON(CKPT_GDT_ENTRY_TLS_ENTRIES != GDT_ENTRY_TLS_ENTRIES);
+ BUILD_BUG_ON(CKPT_TASK_COMM_LEN != TASK_COMM_LEN);
+ BUILD_BUG_ON(CKPT_PAGE_SIZE != PAGE_SIZE); + BUILD_BUG_ON(CKPT_PAGE_SIZE != PAGE_SIZE);
+ +
+ elf_phdr_core = NULL; + elf_phdr_core = NULL;
...@@ -321,6 +322,8 @@ Index: linux-2.6.git/fs/binfmt_elf.c ...@@ -321,6 +322,8 @@ Index: linux-2.6.git/fs/binfmt_elf.c
+ goto out_unmap; + goto out_unmap;
+ } + }
+ +
+ set_task_comm(current, core_entry.comm);
+
+ elf_entry = core_entry.gpregs.ip; + elf_entry = core_entry.gpregs.ip;
+ bprm->p = start_stack; + bprm->p = start_stack;
+ +
...@@ -479,7 +482,7 @@ Index: linux-2.6.git/fs/binfmt_elf.c ...@@ -479,7 +482,7 @@ Index: linux-2.6.git/fs/binfmt_elf.c
static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
{ {
struct file *interpreter = NULL; /* to shut gcc up */ struct file *interpreter = NULL; /* to shut gcc up */
@@ -592,7 +984,9 @@ static int load_elf_binary(struct linux_ @@ -592,7 +987,9 @@ static int load_elf_binary(struct linux_
if (memcmp(loc->elf_ex.e_ident, ELFMAG, SELFMAG) != 0) if (memcmp(loc->elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
goto out; goto out;
...@@ -490,7 +493,7 @@ Index: linux-2.6.git/fs/binfmt_elf.c ...@@ -490,7 +493,7 @@ Index: linux-2.6.git/fs/binfmt_elf.c
goto out; goto out;
if (!elf_check_arch(&loc->elf_ex)) if (!elf_check_arch(&loc->elf_ex))
goto out; goto out;
@@ -619,6 +1013,12 @@ static int load_elf_binary(struct linux_ @@ -619,6 +1016,12 @@ static int load_elf_binary(struct linux_
goto out_free_ph; goto out_free_ph;
} }
...@@ -507,7 +510,7 @@ Index: linux-2.6.git/include/linux/elf_ckpt.h ...@@ -507,7 +510,7 @@ Index: linux-2.6.git/include/linux/elf_ckpt.h
=================================================================== ===================================================================
--- /dev/null --- /dev/null
+++ linux-2.6.git/include/linux/elf_ckpt.h +++ linux-2.6.git/include/linux/elf_ckpt.h
@@ -0,0 +1,135 @@ @@ -0,0 +1,127 @@
+#ifndef _LINUX_ELF_CHECKPOINT_H +#ifndef _LINUX_ELF_CHECKPOINT_H
+#define _LINUX_ELF_CHECKPOINT_H +#define _LINUX_ELF_CHECKPOINT_H
+ +
...@@ -531,6 +534,7 @@ Index: linux-2.6.git/include/linux/elf_ckpt.h ...@@ -531,6 +534,7 @@ Index: linux-2.6.git/include/linux/elf_ckpt.h
+#define PT_CKPT_PAGES (PT_LOOS + PT_CKPT_OFFSET + 3) +#define PT_CKPT_PAGES (PT_LOOS + PT_CKPT_OFFSET + 3)
+ +
+#define CKPT_PAGE_SIZE 4096 +#define CKPT_PAGE_SIZE 4096
+#define CKPT_TASK_COMM_LEN 16
+#define CKPT_GDT_ENTRY_TLS_ENTRIES 3 +#define CKPT_GDT_ENTRY_TLS_ENTRIES 3
+ +
+#define HEADER_VERSION 1 +#define HEADER_VERSION 1
...@@ -604,18 +608,8 @@ Index: linux-2.6.git/include/linux/elf_ckpt.h ...@@ -604,18 +608,8 @@ Index: linux-2.6.git/include/linux/elf_ckpt.h
+} __packed; +} __packed;
+ +
+struct desc_struct_entry { +struct desc_struct_entry {
+ union { + __u32 a;
+ struct { + __u32 b;
+ __u32 a;
+ __u32 b;
+ };
+ struct {
+ __u16 limit0;
+ __u16 base0;
+ unsigned base1: 8, type: 4, s: 1, dpl: 2, p: 1;
+ unsigned limit: 4, avl: 1, l: 1, d: 1, g: 1, base2: 8;
+ };
+ };
+} __packed; +} __packed;
+ +
+struct user_fpregs_entry { +struct user_fpregs_entry {
...@@ -638,6 +632,7 @@ Index: linux-2.6.git/include/linux/elf_ckpt.h ...@@ -638,6 +632,7 @@ Index: linux-2.6.git/include/linux/elf_ckpt.h
+ struct user_fpregs_entry fpregs; + struct user_fpregs_entry fpregs;
+ struct desc_struct tls_array[CKPT_GDT_ENTRY_TLS_ENTRIES]; + struct desc_struct tls_array[CKPT_GDT_ENTRY_TLS_ENTRIES];
+ __u32 personality; + __u32 personality;
+ __u8 comm[CKPT_TASK_COMM_LEN];
+} __packed; +} __packed;
+ +
+#endif /* __KERNEL__ */ +#endif /* __KERNEL__ */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment