diff --git a/fuzzers/frida_libpng/Cargo.toml b/fuzzers/frida_libpng/Cargo.toml
index 306c8a7b41..d3cb3de5a4 100644
--- a/fuzzers/frida_libpng/Cargo.toml
+++ b/fuzzers/frida_libpng/Cargo.toml
@@ -31,7 +31,6 @@ capstone = "0.11.0"
frida-gum = { version = "0.8.1", features = [ "auto-download", "event-sink", "invocation-listener"] }
libafl_frida = { path = "../../libafl_frida", features = ["cmplog"] }
libafl_targets = { path = "../../libafl_targets", features = ["sancov_cmplog"] }
-lazy_static = "1.4.0"
libc = "0.2"
libloading = "0.7"
num-traits = "0.2"
diff --git a/libafl_frida/Cargo.toml b/libafl_frida/Cargo.toml
index 7c6c2a6eaa..36c6679160 100644
--- a/libafl_frida/Cargo.toml
+++ b/libafl_frida/Cargo.toml
@@ -39,3 +39,6 @@ backtrace = { version = "0.3", default-features = false, features = ["std", "ser
num-traits = "0.2"
ahash = "0.7"
paste = "1.0"
+
+[dev-dependencies]
+serial_test = "*"
diff --git a/libafl_frida/src/lib.rs b/libafl_frida/src/lib.rs
index 47ad61d76a..4078d91472 100644
--- a/libafl_frida/src/lib.rs
+++ b/libafl_frida/src/lib.rs
@@ -74,6 +74,10 @@ pub mod windows_hooks;
pub mod coverage_rt;
+/// Hooking thread lifecycle events. Seems like this is apple-only for now.
+#[cfg(any(target_vendor = "apple"))]
+pub mod pthread_hook;
+
#[cfg(feature = "cmplog")]
/// The frida cmplog runtime
pub mod cmplog_rt;
diff --git a/libafl_frida/src/pthread_hook.rs b/libafl_frida/src/pthread_hook.rs
new file mode 100644
index 0000000000..b783aeb5c5
--- /dev/null
+++ b/libafl_frida/src/pthread_hook.rs
@@ -0,0 +1,277 @@
+use std::{
+ cell::UnsafeCell,
+ convert::{TryFrom, TryInto},
+ sync::RwLock,
+};
+
+/// Rust bindings for Apple's [`pthread_introspection`](https://opensource.apple.com/source/libpthread/libpthread-218.20.1/pthread/introspection.h.auto.html) hooks.
+use libc;
+
+const PTHREAD_INTROSPECTION_THREAD_CREATE: libc::c_uint = 1;
+const PTHREAD_INTROSPECTION_THREAD_START: libc::c_uint = 2;
+const PTHREAD_INTROSPECTION_THREAD_TERMINATE: libc::c_uint = 3;
+const PTHREAD_INTROSPECTION_THREAD_DESTROY: libc::c_uint = 4;
+
+#[allow(non_camel_case_types)]
+type pthread_introspection_hook_t = extern "C" fn(
+ event: libc::c_uint,
+ thread: libc::pthread_t,
+ addr: *const libc::c_void,
+ size: libc::size_t,
+);
+
+extern "C" {
+ fn pthread_introspection_hook_install(
+ hook: *const libc::c_void,
+ ) -> pthread_introspection_hook_t;
+}
+
+struct PreviousHook(UnsafeCell