Commit 62ba357e authored by Andrey Vagin's avatar Andrey Vagin Committed by Cyrill Gorcunov

dump: use prctl to dump clear_tid_address

Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Acked-by: 's avatarPavel Emelyanov <xemul@parallels.com>
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
parent fd5520f3
......@@ -1029,10 +1029,12 @@ err:
return -1;
}
static int dump_task_thread(pid_t pid, struct cr_fdset *cr_fdset)
static int dump_task_thread(struct parasite_ctl *parasite_ctl,
pid_t pid, struct cr_fdset *cr_fdset)
{
struct core_entry *core = xzalloc(sizeof(*core));
int ret = -1;
unsigned int *taddr;
pr_info("\n");
pr_info("Dumping core for thread (pid: %d)\n", pid);
......@@ -1045,10 +1047,16 @@ static int dump_task_thread(pid_t pid, struct cr_fdset *cr_fdset)
ret = get_task_regs(pid, core, NULL);
if (ret)
goto err_free;
if (ptrace(PTRACE_GET_TID_ADDRESS, pid, NULL, &core->clear_tid_address)) {
pr_err("Can't get TID address for %d\n", pid);
goto err_free;
ret = parasite_dump_tid_addr_seized(parasite_ctl, pid, &taddr);
if (ret) {
pr_err("Can't dump tid address for pid %d", pid);
goto err;
}
pr_info("%d: tid_address=%p\n", pid, taddr);
core->clear_tid_address = (u64) taddr;
pr_info("OK\n");
core->tc.task_state = TASK_ALIVE;
......@@ -1085,7 +1093,8 @@ static int dump_one_zombie(struct pstree_item *item, struct proc_pid_stat *pps,
static struct proc_pid_stat pps_buf;
static int dump_task_threads(struct pstree_item *item)
static int dump_task_threads(struct parasite_ctl *parasite_ctl,
struct pstree_item *item)
{
int i;
struct cr_fdset *cr_fdset_thread = NULL;
......@@ -1102,7 +1111,8 @@ static int dump_task_threads(struct pstree_item *item)
if (!cr_fdset_thread)
goto err;
if (dump_task_thread(item->threads[i], cr_fdset_thread))
if (dump_task_thread(parasite_ctl,
item->threads[i], cr_fdset_thread))
goto err;
close_cr_fdset(&cr_fdset_thread);
......@@ -1186,7 +1196,7 @@ static int dump_one_task(struct pstree_item *item, struct cr_fdset *cr_fdset)
goto err;
}
ret = dump_task_threads(item);
ret = dump_task_threads(parasite_ctl, item);
if (ret) {
pr_err("Can't dump threads\n");
goto err;
......
......@@ -36,6 +36,10 @@ extern int parasite_dump_misc_seized(struct parasite_ctl *ctl, struct parasite_d
extern int parasite_dump_pages_seized(struct parasite_ctl *ctl,
struct list_head *vma_area_list,
struct cr_fdset *cr_fdset);
struct parasite_dump_tid_addr;
extern int parasite_dump_tid_addr_seized(struct parasite_ctl *ctl,
pid_t pid, unsigned int **tid_add);
extern int parasite_cure_seized(struct parasite_ctl *ctl);
extern struct parasite_ctl *parasite_infect_seized(pid_t pid,
struct list_head *vma_area_list);
......
......@@ -42,6 +42,7 @@ enum {
PARASITE_CMD_DUMP_SIGACTS,
PARASITE_CMD_DUMP_ITIMERS,
PARASITE_CMD_DUMP_MISC,
PARASITE_CMD_DUMP_TID_ADDR,
PARASITE_CMD_MAX,
};
......@@ -90,6 +91,12 @@ struct parasite_dump_misc {
k_rtsigset_t blocked;
};
struct parasite_dump_tid_addr {
parasite_status_t status;
unsigned int *tid_addr;
};
/*
* Some useful offsets
*/
......
......@@ -13,7 +13,6 @@
#endif
#define PTRACE_LISTEN 0x4208
#define PTRACE_GET_TID_ADDRESS 0x4209
#define PTRACE_SEIZE_DEVEL 0x80000000
......
......@@ -41,7 +41,7 @@
# define PR_SET_MM_AUXV 12
# define PR_SET_MM_EXE_FILE 13
#define PR_SETUP_VDSO_AT 36
#define PR_GET_TID_ADDR 36
/* fcntl */
#ifndef F_LINUX_SPECIFIC_BASE
......
......@@ -423,6 +423,19 @@ static int parasite_set_logfd(struct parasite_ctl *ctl, pid_t pid)
return 0;
}
int parasite_dump_tid_addr_seized(struct parasite_ctl *ctl, pid_t pid, unsigned int **tid_addr)
{
struct parasite_dump_tid_addr args = { };
int ret;
ret = parasite_execute_by_pid(PARASITE_CMD_DUMP_TID_ADDR, ctl, pid,
(parasite_status_t *)&args, sizeof(args));
*tid_addr = args.tid_addr;
return ret;
}
int parasite_dump_sigacts_seized(struct parasite_ctl *ctl, struct cr_fdset *cr_fdset)
{
return parasite_file_cmd("sigactions", PARASITE_CMD_DUMP_SIGACTS,
......
......@@ -374,6 +374,17 @@ static int dump_misc(struct parasite_dump_misc *args)
return 0;
}
static int dump_tid_addr(struct parasite_dump_tid_addr *args)
{
parasite_status_t *st = &args->status;
int ret;
ret = sys_prctl(PR_GET_TID_ADDR, (unsigned long) &args->tid_addr, 0, 0, 0);
SET_PARASITE_STATUS(st, 0, ret);
return 0;
}
static int init(struct parasite_init_args *args)
{
int ret;
......@@ -444,6 +455,8 @@ static int __used parasite_service(unsigned long cmd, void *args, void *brk)
return dump_itimers((parasite_status_t *)args);
case PARASITE_CMD_DUMP_MISC:
return dump_misc((struct parasite_dump_misc *)args);
case PARASITE_CMD_DUMP_TID_ADDR:
return dump_tid_addr((struct parasite_dump_tid_addr *)args);
default:
sys_write_msg("Unknown command to parasite\n");
break;
......
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