Use RAII to detach PIDs

This commit is contained in:
topjohnwu 2019-03-10 01:14:41 -05:00
parent 4581354e7a
commit 20f204810e

View File

@ -349,6 +349,7 @@ static void new_zygote(int pid) {
xptrace(PTRACE_CONT, pid); xptrace(PTRACE_CONT, pid);
} }
#define DETACH_AND_CONT { detach = true; continue; }
void proc_monitor() { void proc_monitor() {
inotify_fd = xinotify_init1(IN_CLOEXEC); inotify_fd = xinotify_init1(IN_CLOEXEC);
if (inotify_fd < 0) if (inotify_fd < 0)
@ -384,15 +385,23 @@ void proc_monitor() {
int status; int status;
for (;;) { for (;;) {
int pid = waitpid(-1, &status, __WALL | __WNOTHREAD); const int pid = waitpid(-1, &status, __WALL | __WNOTHREAD);
if (pid < 0) if (pid < 0)
continue; continue;
bool detach = false;
RunFinally detach_task([&]() -> void {
if (detach) {
// Non of our business now
attaches[pid] = false;
detaches[pid] = false;
unknowns[pid] = false;
xptrace(PTRACE_DETACH, pid);
}
});
if (WIFSTOPPED(status)) { if (WIFSTOPPED(status)) {
if (detaches[pid]) { if (detaches[pid]) {
PTRACE_LOG("detach\n"); PTRACE_LOG("detach\n");
detaches[pid] = false; DETACH_AND_CONT;
xptrace(PTRACE_DETACH, pid);
continue;
} }
if (WSTOPSIG(status) == SIGTRAP && WEVENT(status)) { if (WSTOPSIG(status) == SIGTRAP && WEVENT(status)) {
unsigned long msg; unsigned long msg;
@ -427,10 +436,7 @@ void proc_monitor() {
case PTRACE_EVENT_EXEC: case PTRACE_EVENT_EXEC:
case PTRACE_EVENT_EXIT: case PTRACE_EVENT_EXIT:
PTRACE_LOG("exited or execve\n", msg); PTRACE_LOG("exited or execve\n", msg);
attaches[pid] = false; DETACH_AND_CONT;
unknowns[pid] = false;
xptrace(PTRACE_DETACH, pid);
continue;
default: default:
PTRACE_LOG("unknown event: %d\n", WEVENT(status)); PTRACE_LOG("unknown event: %d\n", WEVENT(status));
break; break;
@ -454,8 +460,8 @@ void proc_monitor() {
} }
} else { } else {
// Nothing to do with us // Nothing to do with us
ptrace(PTRACE_DETACH, pid);
PTRACE_LOG("terminate\n"); PTRACE_LOG("terminate\n");
DETACH_AND_CONT;
} }
} }
} }