Skip to content

Commit

Permalink
Don't fail if some threads exit during attach.
Browse files Browse the repository at this point in the history
  • Loading branch information
Roman Rashchupkin committed Mar 5, 2018
1 parent 9752ec3 commit c39a540
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 25 deletions.
32 changes: 19 additions & 13 deletions src/kpatch_process.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
#include <sys/stat.h>
#include <sys/sysmacros.h>

#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ptrace.h>

#include <gelf.h>
#include <libunwind.h>
#include <libunwind-ptrace.h>
Expand Down Expand Up @@ -641,6 +646,7 @@ kpatch_process_attach(kpatch_process_t *proc)
{
int *pids = NULL, ret;
size_t i, npids = 0, alloc = 0, prevnpids = 0, nattempts;
struct kpatch_ptrace_ctx *pctx;

if (kpatch_process_mem_open(proc, MEM_WRITE) < 0)
return -1;
Expand All @@ -653,16 +659,11 @@ kpatch_process_attach(kpatch_process_t *proc)
if (nattempts == 0) {
kpdebug("Found %lu thread(s), attaching...\n", npids);
} else {
/*
* FIXME(pboldin): This is wrong, amount of threads can
* be the same because some new spawned and some old
* died
*/
if (prevnpids == npids)
break;

kpdebug("Found %lu new thread(s), attaching...\n",
prevnpids - npids);
npids - prevnpids);
}

if (proc->is_just_started && npids > 1 && proc->send_fd == -1) {
Expand All @@ -683,20 +684,24 @@ kpatch_process_attach(kpatch_process_t *proc)
goto detach;
}

prevnpids = npids;
prevnpids = 0;
list_for_each_entry(pctx, &proc->ptrace.pctxs, list)
prevnpids++;
}

if (nattempts == max_attach_attempts) {
kperr("unable to catch up with process, bailing\n");
goto detach;
}

kpinfo("attached to %lu thread(s): %d", npids, pids[0]);
for (i = 1; i < npids; i++)
kpinfo(", %d", pids[i]);
kpinfo("\n");

free(pids);
kpinfo("Attached to %lu thread(s):", npids);
list_for_each_entry(pctx, &proc->ptrace.pctxs, list) {
kpinfo(" %d", pctx->pid);
if (pctx->list.next != &proc->ptrace.pctxs)
kpinfo(",");
else
kpinfo("\n");
}

if (proc->ptrace.unwd == NULL) {
proc->ptrace.unwd = unw_create_addr_space(&_UPT_accessors,
Expand All @@ -707,6 +712,7 @@ kpatch_process_attach(kpatch_process_t *proc)
}
}

free(pids);
return 0;

detach:
Expand Down
33 changes: 21 additions & 12 deletions src/kpatch_ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -1126,28 +1126,30 @@ int kpatch_ptrace_attach_thread(kpatch_process_t *proc,
int status;
struct kpatch_ptrace_ctx *pctx;

pctx = kpatch_ptrace_ctx_alloc(proc);
if (pctx == NULL) {
kperr("Can't alloc kpatch_ptrace_ctx");
return -1;
}

pctx->pid = tid;
kpdebug("Attaching to %d...", pctx->pid);

ret = ptrace(PTRACE_ATTACH, pctx->pid, NULL, NULL);
ret = ptrace(PTRACE_ATTACH, tid, NULL, NULL);
if (ret < 0) {
kplogerror("can't attach to %d\n", pctx->pid);
if (errno == ESRCH) {
kpinfo("Thread %d exited before attach.\n", tid);
return 0;
}
kplogerror("can't attach to %d\n", tid);
return -1;
}

kpdebug("Attaching to %d...", tid);

do {
ret = waitpid(tid, &status, __WALL);
if (ret < 0) {
kplogerror("can't wait for thread\n");
return -1;
}

if (WIFEXITED(status)) {
kpinfo("Thread %d exited during attach.\n", tid);
return 0;
}

/* We are expecting SIGSTOP */
if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP)
break;
Expand All @@ -1162,14 +1164,21 @@ int kpatch_ptrace_attach_thread(kpatch_process_t *proc,
status = WTERMSIG(status);


ret = ptrace(PTRACE_CONT, pctx->pid, NULL,
ret = ptrace(PTRACE_CONT, tid, NULL,
(void *)(uintptr_t)status);
if (ret < 0) {
kplogerror("can't cont tracee\n");
return -1;
}
} while (1);

pctx = kpatch_ptrace_ctx_alloc(proc);
if (pctx == NULL) {
kperr("Can't alloc kpatch_ptrace_ctx");
return -1;
}

pctx->pid = tid;
pctx->running = 0;

kpdebug("OK\n");
Expand Down

0 comments on commit c39a540

Please sign in to comment.