Commit 68501cde authored by Ruslan Kuprieiev's avatar Ruslan Kuprieiev Committed by Pavel Emelyanov

dump: dump signals into signals_*

Every thread has it's own private signals stored at thread_core->signals_p
and leader thread has also shared signals stored at tc->signals_s.
Signed-off-by: 's avatarRuslan Kuprieiev <kupruser@gmail.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent aac9fd5b
...@@ -1157,11 +1157,12 @@ err: ...@@ -1157,11 +1157,12 @@ err:
return ret; return ret;
} }
static int dump_signal_queue(pid_t tid, int fd, bool group) static int dump_signal_queue(pid_t tid, SignalQueueEntry **sqe, bool group)
{ {
struct ptrace_peeksiginfo_args arg; struct ptrace_peeksiginfo_args arg;
siginfo_t siginfo[32]; /* One page or all non-rt signals */ siginfo_t siginfo[32]; /* One page or all non-rt signals */
int ret, i = 0, j, nr; int ret, i = 0, j, nr;
SignalQueueEntry *queue = NULL;
pr_debug("Dump %s signals of %d\n", group ? "shared" : "private", tid); pr_debug("Dump %s signals of %d\n", group ? "shared" : "private", tid);
...@@ -1170,6 +1171,12 @@ static int dump_signal_queue(pid_t tid, int fd, bool group) ...@@ -1170,6 +1171,12 @@ static int dump_signal_queue(pid_t tid, int fd, bool group)
if (group) if (group)
arg.flags |= PTRACE_PEEKSIGINFO_SHARED; arg.flags |= PTRACE_PEEKSIGINFO_SHARED;
queue = xmalloc(sizeof(*queue));
if (!queue)
return -1;
signal_queue_entry__init(queue);
for (; ; ) { for (; ; ) {
arg.off = i; arg.off = i;
...@@ -1187,49 +1194,43 @@ static int dump_signal_queue(pid_t tid, int fd, bool group) ...@@ -1187,49 +1194,43 @@ static int dump_signal_queue(pid_t tid, int fd, bool group)
break; break;
nr = ret; nr = ret;
for (j = 0; j < nr; j++) { queue->n_signals += nr;
SiginfoEntry sie = SIGINFO_ENTRY__INIT; queue->signals = xrealloc(queue->signals, sizeof(*queue->signals) * queue->n_signals);
if (!queue->signals) {
ret = -1;
break;
}
sie.siginfo.len = sizeof(siginfo_t); for (j = queue->n_signals - nr; j < queue->n_signals; j++) {
sie.siginfo.data = (void *) (siginfo + j); queue->signals[j]->siginfo.len = sizeof(siginfo_t);
queue->signals[j]->siginfo.data = (void *) (siginfo + j);
ret = pb_write_one(fd, &sie, PB_SIGINFO);
if (ret < 0)
break;
i++; i++;
} }
} }
return ret; *sqe = queue;
}
static int dump_thread_signals(struct pid *tid)
{
int fd, ret;
fd = open_image(CR_FD_PSIGNAL, O_DUMP, tid->virt);
if (fd < 0)
return -1;
ret = dump_signal_queue(tid->real, fd, false);
close(fd);
return ret; return ret;
} }
static int dump_task_signals(pid_t pid, struct pstree_item *item, static int dump_task_signals(pid_t pid, struct pstree_item *item)
struct cr_fdset *cr_fdset)
{ {
int i, ret; int i, ret;
ret = dump_signal_queue(pid, fdset_fd(cr_fdset, CR_FD_SIGNAL), true); /* Dump private signals for each thread */
for (i = 0; i < item->nr_threads; i++) {
ret = dump_signal_queue(item->threads[i].real, &item->core[i]->thread_core->signals_p, false);
if (ret) { if (ret) {
pr_err("Can't dump pending signals (pid: %d)\n", pid); pr_err("Can't dump private signals for thread %d\n", item->threads[i].real);
return -1; return -1;
} }
}
for (i = 0; i < item->nr_threads; i++) { /* Dump shared signals */
ret = dump_thread_signals(&item->threads[i]); ret = dump_signal_queue(pid, &item->core[0]->tc->signals_s, true);
if (ret) if (ret) {
pr_err("Can't dump shared signals (pid: %d)\n", pid);
return -1; return -1;
} }
...@@ -1490,6 +1491,12 @@ static int dump_one_task(struct pstree_item *item) ...@@ -1490,6 +1491,12 @@ static int dump_one_task(struct pstree_item *item)
goto err; goto err;
} }
ret = dump_task_signals(pid, item);
if (ret) {
pr_err("Dump %d signals failed %d\n", pid, ret);
goto err;
}
ret = -1; ret = -1;
parasite_ctl = parasite_infect_seized(pid, item, &vmas, dfds, proc_args.timer_n); parasite_ctl = parasite_infect_seized(pid, item, &vmas, dfds, proc_args.timer_n);
if (!parasite_ctl) { if (!parasite_ctl) {
...@@ -1624,12 +1631,6 @@ static int dump_one_task(struct pstree_item *item) ...@@ -1624,12 +1631,6 @@ static int dump_one_task(struct pstree_item *item)
goto err; goto err;
} }
ret = dump_task_signals(pid, item, cr_fdset);
if (ret) {
pr_err("Dump %d signals failed %d\n", pid, ret);
goto err;
}
close_cr_fdset(&cr_fdset); close_cr_fdset(&cr_fdset);
err: err:
close_pid_proc(); close_pid_proc();
......
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