diff --git a/src/common/mod.rs b/src/common/mod.rs
index 7ad826b3c8b793cd4872df57e6e4ceaea44e6d9d..4bdafba1f5234701e7f4b3c0aec3654f516766ac 100644
--- a/src/common/mod.rs
+++ b/src/common/mod.rs
@@ -1,3 +1,27 @@
 #[macro_use]
 pub mod int_like;
 pub mod unique;
+
+/// Debug macro, lifted from the std
+#[macro_export]
+macro_rules! dbg {
+    () => {
+        $crate::println!("[{}:{}]", file!(), line!());
+    };
+    ($val:expr) => {
+        // Use of `match` here is intentional because it affects the lifetimes
+        // of temporaries - https://stackoverflow.com/a/48732525/1063961
+        match $val {
+            tmp => {
+                $crate::println!("[{}:{}] {} = {:#?}",
+                    file!(), line!(), stringify!($val), &tmp);
+                tmp
+            }
+        }
+    };
+    // Trailing comma with single argument is ignored
+    ($val:expr,) => { $crate::dbg!($val) };
+    ($($val:expr),+ $(,)?) => {
+        ($($crate::dbg!($val)),+,)
+    };
+}
diff --git a/src/syscall/process.rs b/src/syscall/process.rs
index 7d07c4191ad00baf1750211421a76451c0ab7fc7..8165ef0e9c3491f4186c61fe7154d30db87dbfa6 100644
--- a/src/syscall/process.rs
+++ b/src/syscall/process.rs
@@ -1068,8 +1068,6 @@ pub fn exit(status: usize) -> ! {
             context.id
         };
 
-        ptrace::close(pid);
-
         // Files must be closed while context is valid so that messages can be passed
         for (_fd, file_option) in close_files.drain(..).enumerate() {
             if let Some(file) = file_option {
@@ -1110,6 +1108,9 @@ pub fn exit(status: usize) -> ! {
             (vfork, children)
         };
 
+        // Alert any tracers waiting for process (important: AFTER sending waitpid event)
+        ptrace::close(pid);
+
         {
             let contexts = context::contexts();
             if let Some(parent_lock) = contexts.get(ppid) {