Skip to content

Commit 323a116

Browse files
committed
libmach: fix new thread race with Linux
If you look at the sequence of values returned by waitpid, it simply tells us about the child of clone before it tells us that the parent called clone. There's nothing we can do but assume unexpected tids are newly cloned children. Tested with 6prof on godoc. Fixes #251. R=r CC=golang-dev https://golang.org/cl/2167045
1 parent ca9d3f3 commit 323a116

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

src/libmach/linux.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,8 @@ attachthread(int pid, int tid, int *new, int newstate)
202202
memset(t, 0, sizeof *t);
203203

204204
thr[nthr++] = t;
205+
if(pid == 0 && nthr > 0)
206+
pid = thr[0]->pid;
205207
t->pid = pid;
206208
t->tid = tid;
207209
t->state = newstate;
@@ -296,7 +298,9 @@ wait1(int nohang)
296298
if(nohang != 0)
297299
nohang = WNOHANG;
298300

301+
status = 0;
299302
tid = waitpid(-1, &status, __WALL|WUNTRACED|WSTOPPED|WCONTINUED|nohang);
303+
300304
if(tid < 0)
301305
return -1;
302306
if(tid == 0)
@@ -305,11 +309,15 @@ wait1(int nohang)
305309
if(trace > 0 && status != NormalStop)
306310
fprint(2, "TID %d: %#x\n", tid, status);
307311

308-
// If we've not heard of this tid, something is wrong.
309312
t = findthread(tid);
310313
if(t == nil) {
311-
fprint(2, "ptrace waitpid: unexpected new tid %d status %#x\n", tid, status);
312-
return -1;
314+
// Sometimes the kernel tells us about new threads
315+
// before we see the parent clone.
316+
t = attachthread(0, tid, &new, Stopped);
317+
if(t == nil) {
318+
fprint(2, "failed to attach to new thread %d\n", tid);
319+
return -1;
320+
}
313321
}
314322

315323
if(WIFSTOPPED(status)) {
@@ -339,8 +347,6 @@ wait1(int nohang)
339347
}
340348
t->child = data;
341349
attachthread(t->pid, t->child, &new, Running);
342-
if(!new)
343-
fprint(2, "ptrace child: not new\n");
344350
break;
345351

346352
case PTRACE_EVENT_EXEC:

0 commit comments

Comments
 (0)