diff --git a/Cargo.toml b/Cargo.toml
index 2994acfe053943df6a0ff52d36f2b8e8901e3b2b..03dc0349d493bf75828a645f6828688665a1d8ca 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -22,6 +22,7 @@ std = ["cbor/std", "crypto/std", "crypto/derive_debug"]
 debug_ctap = ["crypto/derive_debug"]
 with_ctap1 = ["crypto/with_ctap1"]
 panic_console = ["libtock/panic_console"]
+debug_allocations = ["libtock/debug_allocations"]
 
 [dev-dependencies]
 elf2tab = "0.4.0"
diff --git a/deploy.py b/deploy.py
index 1dc3fc8410ec1289e5b253342f3e3af638420668..85515a6a8933400d7538b212b7f6d57166277b2c 100755
--- a/deploy.py
+++ b/deploy.py
@@ -366,6 +366,14 @@ if __name__ == '__main__':
             "output messages before starting blinking the LEDs on the "
             "board."),
   )
+  app_commands.add_argument(
+      "--debug-allocations",
+      action="append_const",
+      const="debug_allocations",
+      dest="features",
+      help=("The console will be used to output allocator statistics every "
+            "yime an allocation/deallocation happens."),
+  )
   app_commands.add_argument(
       "--no-u2f",
       action=RemoveConstAction,
diff --git a/patches/libtock-rs/07-debug_allocations.patch b/patches/libtock-rs/07-debug_allocations.patch
new file mode 100644
index 0000000000000000000000000000000000000000..0b874bed11783514c35212c4613102e4cd6f60ea
--- /dev/null
+++ b/patches/libtock-rs/07-debug_allocations.patch
@@ -0,0 +1,98 @@
+diff --git a/Cargo.toml b/Cargo.toml
+index 386a9ed..af3c5db 100644
+--- a/Cargo.toml
++++ b/Cargo.toml
+@@ -10,6 +10,7 @@ linked_list_allocator = { version = "0.6.6", default-features = false }
+ 
+ [features]
+ panic_console = []
++debug_allocations = []
+ 
+ [dev-dependencies]
+ corepack = { version = "0.4.0", default-features = false, features = ["alloc"] }
+diff --git a/src/entry_point.rs b/src/entry_point.rs
+index 2fe5c40..c978ee5 100644
+--- a/src/entry_point.rs
++++ b/src/entry_point.rs
+@@ -368,22 +368,77 @@ pub unsafe extern "C" fn rust_start(app_start: usize, stacktop: usize, app_heap_
+     }
+ }
+ 
++#[cfg(feature = "debug_allocations")]
++use core::fmt::Write;
++#[cfg(feature = "debug_allocations")]
++use core::sync::atomic;
++#[cfg(feature = "debug_allocations")]
++use core::sync::atomic::AtomicUsize;
++
+ #[cfg(any(target_arch = "arm", target_arch = "riscv32"))]
+ #[global_allocator]
+-static ALLOCATOR: TockAllocator = TockAllocator;
++static ALLOCATOR: TockAllocator = TockAllocator::new();
+ 
+ static mut HEAP: Heap = Heap::empty();
+ 
+-struct TockAllocator;
++struct TockAllocator {
++    #[cfg(feature = "debug_allocations")]
++    count: AtomicUsize,
++    #[cfg(feature = "debug_allocations")]
++    size: AtomicUsize,
++}
++
++impl TockAllocator {
++    const fn new() -> TockAllocator {
++        TockAllocator {
++            #[cfg(feature = "debug_allocations")]
++            count: AtomicUsize::new(0),
++            #[cfg(feature = "debug_allocations")]
++            size: AtomicUsize::new(0),
++        }
++    }
++}
+ 
+ unsafe impl GlobalAlloc for TockAllocator {
+     unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+-        HEAP.allocate_first_fit(layout)
++        let ptr = HEAP
++            .allocate_first_fit(layout)
+             .ok()
+-            .map_or(0 as *mut u8, |allocation| allocation.as_ptr())
++            .map_or(ptr::null_mut(), NonNull::as_ptr);
++        #[cfg(feature = "debug_allocations")]
++        {
++            self.count.fetch_add(1, atomic::Ordering::SeqCst);
++            self.size.fetch_add(layout.size(), atomic::Ordering::SeqCst);
++            writeln!(
++                crate::console::Console::new(),
++                "alloc[{}, {}] = {:?} ({} ptrs, {} bytes)",
++                layout.size(),
++                layout.align(),
++                ptr,
++                self.count.load(atomic::Ordering::SeqCst),
++                self.size.load(atomic::Ordering::SeqCst)
++            )
++            .unwrap();
++        }
++        ptr
+     }
+ 
+     unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
++        #[cfg(feature = "debug_allocations")]
++        {
++            self.count.fetch_sub(1, atomic::Ordering::SeqCst);
++            self.size.fetch_sub(layout.size(), atomic::Ordering::SeqCst);
++            writeln!(
++                crate::console::Console::new(),
++                "dealloc[{}, {}] = {:?} ({} ptrs, {} bytes)",
++                layout.size(),
++                layout.align(),
++                ptr,
++                self.count.load(atomic::Ordering::SeqCst),
++                self.size.load(atomic::Ordering::SeqCst)
++            )
++            .unwrap();
++        }
+         HEAP.deallocate(NonNull::new_unchecked(ptr), layout)
+     }
+ }