Skip to content

Commit be18093

Browse files
author
Roman Rashchupkin
committed
Don't fail if some threads exit during attach.
1 parent 9752ec3 commit be18093

File tree

2 files changed

+36
-20
lines changed

2 files changed

+36
-20
lines changed

src/kpatch_process.c

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
#include <sys/stat.h>
1313
#include <sys/sysmacros.h>
1414

15+
#include <sys/syscall.h>
16+
#include <sys/types.h>
17+
#include <sys/wait.h>
18+
#include <sys/ptrace.h>
19+
1520
#include <gelf.h>
1621
#include <libunwind.h>
1722
#include <libunwind-ptrace.h>
@@ -641,6 +646,7 @@ kpatch_process_attach(kpatch_process_t *proc)
641646
{
642647
int *pids = NULL, ret;
643648
size_t i, npids = 0, alloc = 0, prevnpids = 0, nattempts;
649+
struct kpatch_ptrace_ctx *pctx;
644650

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

664665
kpdebug("Found %lu new thread(s), attaching...\n",
665-
prevnpids - npids);
666+
npids - prevnpids);
666667
}
667668

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

686-
prevnpids = npids;
687+
prevnpids = 0;
688+
list_for_each_entry(pctx, &proc->ptrace.pctxs, list)
689+
prevnpids++;
687690
}
688691

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

694-
kpinfo("attached to %lu thread(s): %d", npids, pids[0]);
695-
for (i = 1; i < npids; i++)
696-
kpinfo(", %d", pids[i]);
697-
kpinfo("\n");
698-
699-
free(pids);
697+
kpinfo("Attached to %lu thread(s):", npids);
698+
list_for_each_entry(pctx, &proc->ptrace.pctxs, list) {
699+
kpinfo(" %d", pctx->pid);
700+
if (pctx->list.next != &proc->ptrace.pctxs)
701+
kpinfo(",");
702+
else
703+
kpinfo("\n");
704+
}
700705

701706
if (proc->ptrace.unwd == NULL) {
702707
proc->ptrace.unwd = unw_create_addr_space(&_UPT_accessors,
@@ -707,6 +712,7 @@ kpatch_process_attach(kpatch_process_t *proc)
707712
}
708713
}
709714

715+
free(pids);
710716
return 0;
711717

712718
detach:

src/kpatch_ptrace.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,20 +1126,24 @@ int kpatch_ptrace_attach_thread(kpatch_process_t *proc,
11261126
int status;
11271127
struct kpatch_ptrace_ctx *pctx;
11281128

1129+
ret = ptrace(PTRACE_ATTACH, tid, NULL, NULL);
1130+
if (ret < 0) {
1131+
if (errno == ESRCH) {
1132+
kpinfo("Thread %d exited before attach.\n", tid);
1133+
return 0;
1134+
}
1135+
kplogerror("can't attach to %d\n", tid);
1136+
return -1;
1137+
}
1138+
11291139
pctx = kpatch_ptrace_ctx_alloc(proc);
11301140
if (pctx == NULL) {
11311141
kperr("Can't alloc kpatch_ptrace_ctx");
11321142
return -1;
11331143
}
1134-
11351144
pctx->pid = tid;
1136-
kpdebug("Attaching to %d...", pctx->pid);
11371145

1138-
ret = ptrace(PTRACE_ATTACH, pctx->pid, NULL, NULL);
1139-
if (ret < 0) {
1140-
kplogerror("can't attach to %d\n", pctx->pid);
1141-
return -1;
1142-
}
1146+
kpdebug("Attaching to %d...", pctx->pid);
11431147

11441148
do {
11451149
ret = waitpid(tid, &status, __WALL);
@@ -1148,6 +1152,12 @@ int kpatch_ptrace_attach_thread(kpatch_process_t *proc,
11481152
return -1;
11491153
}
11501154

1155+
if (WIFEXITED(status)) {
1156+
kpinfo("Thread %d exited during attach.\n", tid);
1157+
kpatch_ptrace_ctx_destroy(pctx);
1158+
return 0;
1159+
}
1160+
11511161
/* We are expecting SIGSTOP */
11521162
if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP)
11531163
break;

0 commit comments

Comments
 (0)