diff --git a/src/arch/x86_64/interrupt/syscall.rs b/src/arch/x86_64/interrupt/syscall.rs
index ebc3c528c1e72294dd5fc4ade15fa499e9f32729..6b9dfe615db217d6f51180a3dc9f23d84f1998fd 100644
--- a/src/arch/x86_64/interrupt/syscall.rs
+++ b/src/arch/x86_64/interrupt/syscall.rs
@@ -21,7 +21,8 @@ macro_rules! with_interrupt_stack {
         unsafe fn $wrapped(stack: *mut InterruptStack) {
             let _guard = ptrace::set_process_regs(stack);
 
-            let is_sysemu = ptrace::breakpoint_callback(::syscall::PTRACE_SYSCALL);
+            let is_sysemu = ptrace::breakpoint_callback(syscall::flag::PTRACE_SYSCALL)
+                .map(|fl| fl & syscall::flag::PTRACE_SYSEMU == syscall::flag::PTRACE_SYSEMU);
             if !is_sysemu.unwrap_or(false) {
                 // If not on a sysemu breakpoint
                 let $stack = &mut *stack;
diff --git a/src/context/signal.rs b/src/context/signal.rs
index f7db1ae3fc31774ce81d3bc968d42022e1fe7a65..d5d2ff18cb3e48918ca16cb2532148fa6856b648 100644
--- a/src/context/signal.rs
+++ b/src/context/signal.rs
@@ -3,8 +3,9 @@ use core::mem;
 
 use crate::context::{contexts, switch, Status, WaitpidKey};
 use crate::start::usermode;
-use crate::syscall;
-use crate::syscall::flag::{SIG_DFL, SIG_IGN, SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU};
+use crate::{ptrace, syscall};
+use crate::syscall::flag::{PTRACE_EVENT_SIGNAL, PTRACE_SIGNAL, SIG_DFL, SIG_IGN, SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU};
+use crate::syscall::data::{PtraceEvent, PtraceEventData};
 
 pub fn is_user_handled(handler: Option<extern "C" fn(usize)>) -> bool {
     let handler = handler.map(|ptr| ptr as usize).unwrap_or(0);
@@ -20,6 +21,11 @@ pub extern "C" fn signal_handler(sig: usize) {
         actions[sig]
     };
 
+    ptrace::send_event(PtraceEvent {
+        tag: PTRACE_EVENT_SIGNAL,
+        data: PtraceEventData { signal: sig }
+    });
+
     let handler = action.sa_handler.map(|ptr| ptr as usize).unwrap_or(0);
     if handler == SIG_DFL {
         match sig {
@@ -94,6 +100,8 @@ pub extern "C" fn signal_handler(sig: usize) {
     } else {
         // println!("Call {:X}", handler);
 
+        ptrace::breakpoint_callback(PTRACE_SIGNAL);
+
         unsafe {
             let mut sp = crate::USER_SIGSTACK_OFFSET + crate::USER_SIGSTACK_SIZE - 256;
 
diff --git a/src/ptrace.rs b/src/ptrace.rs
index ae7d9b18a2c480bb53451804df134ec59f1daec5..3f3390f492b7a6ee1b4bdb32737a3723f35c44dc 100644
--- a/src/ptrace.rs
+++ b/src/ptrace.rs
@@ -114,7 +114,7 @@ pub fn close_session(pid: ContextId) {
 }
 
 /// Trigger a notification to the event: scheme
-pub fn proc_trigger_event(file_id: usize, flags: usize) {
+fn proc_trigger_event(file_id: usize, flags: usize) {
     event::trigger(proc::PROC_SCHEME_ID.load(Ordering::SeqCst), file_id, flags);
 }
 
@@ -244,9 +244,9 @@ pub fn wait(pid: ContextId) -> Result<Option<PtraceEvent>> {
 
 /// Notify the tracer and await green flag to continue.
 /// Note: Don't call while holding any locks, this will switch contexts
-pub fn breakpoint_callback(flags: u8) -> Option<bool> {
+pub fn breakpoint_callback(match_flags: u8) -> Option<u8> {
     // Can't hold any locks when executing wait()
-    let (tracee, sysemu) = {
+    let (tracee, flags) = {
         let contexts = context::contexts();
         let context = contexts.current()?;
         let context = context.read();
@@ -258,7 +258,7 @@ pub fn breakpoint_callback(flags: u8) -> Option<bool> {
         // TODO: How should singlesteps interact with syscalls? How
         // does Linux handle this?
 
-        if breakpoint.flags & PTRACE_OPERATIONMASK != flags & PTRACE_OPERATIONMASK {
+        if breakpoint.flags & PTRACE_OPERATIONMASK != match_flags & PTRACE_OPERATIONMASK {
             return None;
         }
 
@@ -271,13 +271,13 @@ pub fn breakpoint_callback(flags: u8) -> Option<bool> {
 
         (
             Arc::clone(&breakpoint.tracee),
-            breakpoint.flags & PTRACE_SYSEMU == PTRACE_SYSEMU
+            breakpoint.flags
         )
     };
 
     while !tracee.wait() {}
 
-    Some(sysemu)
+    Some(flags)
 }
 
 /// Call when a context is closed to alert any tracers
diff --git a/src/scheme/proc.rs b/src/scheme/proc.rs
index 3e7d34a115650c3c6cb08785b1fad1a05897e864..5a04f9d55479a2b881ae11307eefb059c93d5ff4 100644
--- a/src/scheme/proc.rs
+++ b/src/scheme/proc.rs
@@ -374,7 +374,7 @@ impl Scheme for ProcScheme {
 
                 match op & PTRACE_OPERATIONMASK {
                     PTRACE_CONT => { ptrace::cont(pid); },
-                    PTRACE_SYSCALL | PTRACE_SINGLESTEP => { // <- not a bitwise OR
+                    PTRACE_SYSCALL | PTRACE_SINGLESTEP | PTRACE_SIGNAL => { // <- not a bitwise OR
                         singlestep = op & PTRACE_OPERATIONMASK == PTRACE_SINGLESTEP;
                         ptrace::set_breakpoint(pid, op);
                     },
diff --git a/src/syscall/process.rs b/src/syscall/process.rs
index 9a74c0a23ac3d45c9f62b2975e79354d4e62af9f..e683b4cfc644beeaff9d50765ad20fd31fcbbbd7 100644
--- a/src/syscall/process.rs
+++ b/src/syscall/process.rs
@@ -21,7 +21,7 @@ use crate::paging::{ActivePageTable, InactivePageTable, Page, VirtualAddress, PA
 use crate::ptrace;
 use crate::scheme::FileHandle;
 use crate::start::usermode;
-use crate::syscall::data::{PtraceEvent, PtraceEventContent, SigAction, Stat};
+use crate::syscall::data::{PtraceEvent, PtraceEventData, SigAction, Stat};
 use crate::syscall::error::*;
 use crate::syscall::flag::{CLONE_VFORK, CLONE_VM, CLONE_FS, CLONE_FILES, CLONE_SIGHAND, CLONE_STACK,
                            PROT_EXEC, PROT_READ, PROT_WRITE, PTRACE_EVENT_CLONE,
@@ -587,7 +587,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
 
     let ptrace_event = PtraceEvent {
         tag: PTRACE_EVENT_CLONE,
-        data: PtraceEventContent {
+        data: PtraceEventData {
             clone: pid.into()
         }
     };
@@ -1124,9 +1124,6 @@ pub fn exit(status: usize) -> ! {
             (vfork, children)
         };
 
-        // Alert any tracers waiting for process (important: AFTER sending waitpid event)
-        ptrace::close_tracee(pid);
-
         {
             let contexts = context::contexts();
             if let Some(parent_lock) = contexts.get(ppid) {
@@ -1153,6 +1150,9 @@ pub fn exit(status: usize) -> ! {
             }
         }
 
+        // Alert any tracers waiting for process (important: AFTER sending waitpid event)
+        ptrace::close_tracee(pid);
+
         if pid == ContextId::from(1) {
             println!("Main kernel thread exited with status {:X}", status);
 
diff --git a/syscall b/syscall
index f3bb1f7b68bc8e5544857781de9eb8729b2843f4..844650c4fb9725cd9029de6277826bfe0fb19909 160000
--- a/syscall
+++ b/syscall
@@ -1 +1 @@
-Subproject commit f3bb1f7b68bc8e5544857781de9eb8729b2843f4
+Subproject commit 844650c4fb9725cd9029de6277826bfe0fb19909