Merge branch 'master' of ssh://github.com/google/honggfuzz
diff --git a/linux/arch.c b/linux/arch.c
index 3d962d5..dceb7fc 100644
--- a/linux/arch.c
+++ b/linux/arch.c
@@ -330,6 +330,9 @@
     }
     arch_removeTimer(&timerid);
     arch_perfAnalyze(hfuzz, fuzzer, &perfFds);
+    if (childPid != ptracePid) {
+        arch_ptraceDetach(ptracePid);
+    }
     return;
 }
 
diff --git a/linux/ptrace_utils.c b/linux/ptrace_utils.c
index d7de1e9..755cdb6 100644
--- a/linux/ptrace_utils.c
+++ b/linux/ptrace_utils.c
@@ -909,9 +909,9 @@
     return true;
 }
 
+#define MAX_THREAD_IN_TASK 4096
 bool arch_ptraceAttach(pid_t pid)
 {
-#define MAX_THREAD_IN_TASK 4096
     int tasks[MAX_THREAD_IN_TASK + 1] = { 0 };
     if (!arch_listThreads(tasks, MAX_THREAD_IN_TASK, pid)) {
         LOGMSG(l_ERROR, "Couldn't read thread list for pid '%d'", pid);
@@ -933,3 +933,19 @@
     }
     return true;
 }
+
+void arch_ptraceDetach(pid_t pid)
+{
+    int tasks[MAX_THREAD_IN_TASK + 1] = { 0 };
+    if (!arch_listThreads(tasks, MAX_THREAD_IN_TASK, pid)) {
+        LOGMSG(l_ERROR, "Couldn't read thread list for pid '%d'", pid);
+        return;
+    }
+
+    for (int i = 0; i < MAX_THREAD_IN_TASK && tasks[i]; i++) {
+        ptrace(PTRACE_INTERRUPT, tasks[i], NULL, NULL);
+        int status;
+        while (wait4(tasks[i], &status, __WALL, NULL) != pid) ;
+        ptrace(PTRACE_DETACH, tasks[i], NULL, NULL);
+    }
+}
diff --git a/linux/ptrace_utils.h b/linux/ptrace_utils.h
index 041324f..300ce7c 100644
--- a/linux/ptrace_utils.h
+++ b/linux/ptrace_utils.h
@@ -30,6 +30,7 @@
 extern bool arch_ptraceEnable(honggfuzz_t * fuzz);
 extern void arch_ptraceAnalyze(honggfuzz_t * fuzz, int status, pid_t pid, fuzzer_t * fuzzer);
 extern bool arch_ptraceAttach(pid_t pid);
+extern void arch_ptraceDetach(pid_t pid);
 extern void arch_ptraceGetCustomPerf(honggfuzz_t * fuzz, pid_t pid, uint64_t * cnt);
 
 #endif