Commit de75a0a3 authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Pavel Emelyanov

dump: Add dumping of alternative signal stack

[alekskartashov@: use encode_pointer]
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
CC: Alexander Kartashov <alekskartashov@parallels.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 1ca1a5b2
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <sys/un.h> #include <sys/un.h>
#include <time.h> #include <time.h>
#include <signal.h>
#include "image.h" #include "image.h"
#include "util-net.h" #include "util-net.h"
...@@ -71,6 +72,7 @@ struct parasite_init_args { ...@@ -71,6 +72,7 @@ struct parasite_init_args {
k_rtsigset_t sig_blocked; k_rtsigset_t sig_blocked;
struct rt_sigframe *sigframe; struct rt_sigframe *sigframe;
stack_t sas;
}; };
struct parasite_log_args { struct parasite_log_args {
...@@ -163,6 +165,7 @@ struct parasite_dump_thread { ...@@ -163,6 +165,7 @@ struct parasite_dump_thread {
pid_t tid; pid_t tid;
k_rtsigset_t blocked; k_rtsigset_t blocked;
u32 tls; u32 tls;
stack_t sas;
}; };
#define PARASITE_MAX_FDS (PAGE_SIZE / sizeof(int)) #define PARASITE_MAX_FDS (PAGE_SIZE / sizeof(int))
......
...@@ -370,7 +370,14 @@ static int parasite_set_logfd(struct parasite_ctl *ctl, pid_t pid) ...@@ -370,7 +370,14 @@ static int parasite_set_logfd(struct parasite_ctl *ctl, pid_t pid)
return 0; return 0;
} }
static int parasite_init(struct parasite_ctl *ctl, pid_t pid, int nr_threads) static void copy_sas(ThreadSasEntry *dst, stack_t *src)
{
dst->ss_sp = encode_pointer(src->ss_sp);
dst->ss_size = (u64)src->ss_size;
dst->ss_flags = src->ss_flags;
}
static int parasite_init(struct parasite_ctl *ctl, pid_t pid, struct pstree_item *item)
{ {
static int ssock = -1; static int ssock = -1;
...@@ -421,6 +428,9 @@ static int parasite_init(struct parasite_ctl *ctl, pid_t pid, int nr_threads) ...@@ -421,6 +428,9 @@ static int parasite_init(struct parasite_ctl *ctl, pid_t pid, int nr_threads)
ctl->sig_blocked = args->sig_blocked; ctl->sig_blocked = args->sig_blocked;
ctl->use_sig_blocked = true; ctl->use_sig_blocked = true;
BUG_ON(!item->core[0]->thread_core->sas);
copy_sas(item->core[0]->thread_core->sas, &args->sas);
sock = accept(ssock, NULL, 0); sock = accept(ssock, NULL, 0);
if (sock < 0) { if (sock < 0) {
pr_perror("Can't accept connection to the transport socket"); pr_perror("Can't accept connection to the transport socket");
...@@ -516,6 +526,9 @@ int parasite_dump_thread_seized(struct parasite_ctl *ctl, int id, ...@@ -516,6 +526,9 @@ int parasite_dump_thread_seized(struct parasite_ctl *ctl, int id,
memcpy(&core->thread_core->blk_sigset, memcpy(&core->thread_core->blk_sigset,
&args->blocked, sizeof(k_rtsigset_t)); &args->blocked, sizeof(k_rtsigset_t));
core->thread_core->has_blk_sigset = true; core->thread_core->has_blk_sigset = true;
BUG_ON(!core->thread_core->sas);
copy_sas(core->thread_core->sas, &args->sas);
} }
CORE_THREAD_ARCH_INFO(core)->clear_tid_addr = encode_pointer(args->tid_addr); CORE_THREAD_ARCH_INFO(core)->clear_tid_addr = encode_pointer(args->tid_addr);
...@@ -1069,7 +1082,7 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, ...@@ -1069,7 +1082,7 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
p += PARASITE_STACK_SIZE; p += PARASITE_STACK_SIZE;
} }
ret = parasite_init(ctl, pid, item->nr_threads); ret = parasite_init(ctl, pid, item);
if (ret) { if (ret) {
pr_err("%d: Can't create a transport socket\n", pid); pr_err("%d: Can't create a transport socket\n", pid);
goto err_restore; goto err_restore;
......
...@@ -230,6 +230,9 @@ static int init_thread(struct parasite_dump_thread *args) ...@@ -230,6 +230,9 @@ static int init_thread(struct parasite_dump_thread *args)
args->tid = tid; args->tid = tid;
args->tls = arch_get_tls(); args->tls = arch_get_tls();
ret = sys_sigaltstack(NULL, &args->sas);
if (ret)
goto err;
return ret; return ret;
err: err:
...@@ -258,6 +261,10 @@ static int init(struct parasite_init_args *args) ...@@ -258,6 +261,10 @@ static int init(struct parasite_init_args *args)
if (ret) if (ret)
return -1; return -1;
ret = sys_sigaltstack(NULL, &args->sas);
if (ret)
goto err;
tsock = sys_socket(PF_UNIX, SOCK_STREAM, 0); tsock = sys_socket(PF_UNIX, SOCK_STREAM, 0);
if (tsock < 0) { if (tsock < 0) {
ret = tsock; ret = tsock;
......
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