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 @@
#include <sys/ptrace.h>
#include <sys/user.h>
#include <sys/wait.h>
#include <sys/prctl.h>
#include <sys/sendfile.h>
......@@ -404,6 +405,40 @@ err:
#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))
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)
{
FILE *file = NULL;
......@@ -558,6 +593,12 @@ static int dump_task_core_seized(pid_t pid, struct cr_fdset *cr_fdset)
goto err_free;
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 ... ");
core->hdr.version = HEADER_VERSION;
core->hdr.arch = HEADER_ARCH_X86_64;
......
......@@ -65,7 +65,7 @@ static void free_pstree(void)
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 desc_struct tls;
......@@ -102,6 +102,28 @@ err:
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)
{
struct fdinfo_entry e;
......@@ -188,7 +210,8 @@ static void show_core(struct cr_fdset *cr_fdset)
if (fd_core < 0)
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);
......
......@@ -137,18 +137,8 @@ struct user_regs_entry {
} __packed;
struct desc_struct {
union {
struct {
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;
};
};
u32 a;
u32 b;
} __packed;
struct user_fpregs_entry {
......@@ -167,6 +157,7 @@ struct user_fpregs_entry {
} __packed;
#define GDT_ENTRY_TLS_ENTRIES 3
#define TASK_COMM_LEN 16
struct core_entry {
struct image_header hdr;
......@@ -174,6 +165,7 @@ struct core_entry {
struct user_fpregs_entry fpregs;
struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
u32 personality;
u8 comm[TASK_COMM_LEN];
} __packed;
#endif /* CONFIG_X86_64 */
......
......@@ -18,9 +18,9 @@ Signed-off-by: Andrew Vagin <avagin@openvz.org>
---
arch/x86/include/asm/elf.h | 3
arch/x86/vdso/vma.c | 22 ++
fs/binfmt_elf.c | 402 ++++++++++++++++++++++++++++++++++++++++++++-
include/linux/elf_ckpt.h | 135 +++++++++++++++
4 files changed, 560 insertions(+), 2 deletions(-)
fs/binfmt_elf.c | 405 ++++++++++++++++++++++++++++++++++++++++++++-
include/linux/elf_ckpt.h | 127 ++++++++++++++
4 files changed, 555 insertions(+), 2 deletions(-)
Index: linux-2.6.git/arch/x86/include/asm/elf.h
===================================================================
......@@ -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_library(struct file *);
@@ -556,6 +564,390 @@ static unsigned long randomize_stack_top
@@ -556,6 +564,393 @@ static unsigned long randomize_stack_top
#endif
}
......@@ -120,6 +120,7 @@ Index: linux-2.6.git/fs/binfmt_elf.c
+ int cpu;
+
+ 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);
+
+ elf_phdr_core = NULL;
......@@ -321,6 +322,8 @@ Index: linux-2.6.git/fs/binfmt_elf.c
+ goto out_unmap;
+ }
+
+ set_task_comm(current, core_entry.comm);
+
+ elf_entry = core_entry.gpregs.ip;
+ bprm->p = start_stack;
+
......@@ -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)
{
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)
goto out;
......@@ -490,7 +493,7 @@ Index: linux-2.6.git/fs/binfmt_elf.c
goto out;
if (!elf_check_arch(&loc->elf_ex))
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;
}
......@@ -507,7 +510,7 @@ Index: linux-2.6.git/include/linux/elf_ckpt.h
===================================================================
--- /dev/null
+++ linux-2.6.git/include/linux/elf_ckpt.h
@@ -0,0 +1,135 @@
@@ -0,0 +1,127 @@
+#ifndef _LINUX_ELF_CHECKPOINT_H
+#define _LINUX_ELF_CHECKPOINT_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 CKPT_PAGE_SIZE 4096
+#define CKPT_TASK_COMM_LEN 16
+#define CKPT_GDT_ENTRY_TLS_ENTRIES 3
+
+#define HEADER_VERSION 1
......@@ -604,18 +608,8 @@ Index: linux-2.6.git/include/linux/elf_ckpt.h
+} __packed;
+
+struct desc_struct_entry {
+ union {
+ struct {
+ __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;
+ };
+ };
+ __u32 a;
+ __u32 b;
+} __packed;
+
+struct user_fpregs_entry {
......@@ -638,6 +632,7 @@ Index: linux-2.6.git/include/linux/elf_ckpt.h
+ struct user_fpregs_entry fpregs;
+ struct desc_struct tls_array[CKPT_GDT_ENTRY_TLS_ENTRIES];
+ __u32 personality;
+ __u8 comm[CKPT_TASK_COMM_LEN];
+} __packed;
+
+#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