MemViz v1.0.0
C++ Memory Layout Inspector
Loading...
Searching...
No Matches
MemoryTracker.hpp
Go to the documentation of this file.
1#pragma once
2#include <vector>
3#include <mutex>
4#include <cstdint>
5#include <iostream>
6#include <cstdint>
7
8
9namespace memviz {
10 /*
11 * @brief Metadata stored for each tracked allocation.
12 */
14 std::uintptr_t ptr;
15 std::size_t size;
16 };
17 namespace detail {
18 inline thread_local bool in_hook = false;
19
20 struct HookGuard {
21 bool armed = false;
23 if (!in_hook) { in_hook = true; armed = true; }
24 }
26 if (armed) in_hook = false;
27 }
28
29 };
30
31 inline auto lower_bound_addr(std::vector<AllocationInfo>& t, std::uintptr_t addr) {
32 return std::lower_bound(t.begin(), t.end(), addr,
33 [](const AllocationInfo& a, std::uintptr_t k){ return a.ptr < k; });
34 }
35 } // namespace detail
36
37
38static inline std::uintptr_t key_of(const void* p) noexcept {
39 return reinterpret_cast<std::uintptr_t>(p);
40}
41
50inline auto& table() {
51 static auto* m = new std::vector<AllocationInfo>();
52 return *m;
53}
54
55
61inline std::mutex& lock() {
62 static auto* mu = new std::mutex();
63 return *mu;
64}
65
75inline void on_alloc(const void* ptr, std::size_t sz) {
76 if (!ptr)
77 return;
78
80
81 if (!g.armed)
82 return; // already inside: skip
83
84 std::scoped_lock _(lock());
85
86 const auto addr = key_of(ptr);
87
88 auto it = detail::lower_bound_addr(table(), addr);
89 if (it != table().end() && it->ptr == addr) {
90 it->size = sz;
91 } else {
92 table().insert(it, AllocationInfo{addr, sz}); // keeps vector sorted
93 }
94}
95
96
105inline void on_free(const void* ptr) {
106 if (!ptr) return;
108 if (!g.armed) return;
109
110 std::scoped_lock lk(lock());
111 auto& t = table();
112 const auto addr = key_of(ptr);
113
114 auto it = detail::lower_bound_addr(t, addr);
115 if (it != t.end() && it->ptr == addr) {
116 t.erase(it);
117 }
118}
119
126[[nodiscard]] inline bool isLive(const void* ptr) {
127 std::scoped_lock lk(lock());
128 const auto& t = table();
129 const auto addr = key_of(ptr);
130
131 auto it = detail::lower_bound_addr(const_cast<std::vector<AllocationInfo>&>(t), addr);
132 return it != t.end() && it->ptr == addr;
133}
134
143inline void reportLeaks(std::ostream& os = std::cout) {
144 std::scoped_lock g(lock());
145 std::size_t total_bytes = 0;
146 int i = 0;
147
148 for (const auto& info : table()) {
149
150 os << "[" << i++ << "] LEAK " << reinterpret_cast<void*>(info.ptr) << " (" << info.size << " bytes)\n";
151 total_bytes += info.size;
152 }
153 os << "[SUMMARY] " << i << " potential leak(s), total " << total_bytes << " bytes.\n";
154}
155
164inline void printAllocationLog(std::ostream& os = std::cout) {
165 std::scoped_lock g(lock());
166 std::size_t i = 0;
167 for (const auto& info : table()) {
168 os << "[" << i++ << "] LIVE " << reinterpret_cast<void*>(info.ptr) << " (" << info.size << " bytes)\n";
169 }
170}
171
172} // namespace memviz
auto lower_bound_addr(std::vector< AllocationInfo > &t, std::uintptr_t addr)
Definition MemoryTracker.hpp:31
thread_local bool in_hook
Definition MemoryTracker.hpp:18
Definition BitCaster.hpp:5
std::mutex & lock()
Access the global mutex used to protect the table.
Definition MemoryTracker.hpp:61
auto & table()
Access the singleton allocation table.
Definition MemoryTracker.hpp:50
void printAllocationLog(std::ostream &os=std::cout)
Print all currently tracked allocations.
Definition MemoryTracker.hpp:164
void reportLeaks(std::ostream &os=std::cout)
Print a summary of all currently live allocations (potential leaks).
Definition MemoryTracker.hpp:143
bool isLive(const void *ptr)
Check if a pointer is currently tracked as allocated.
Definition MemoryTracker.hpp:126
void on_alloc(const void *ptr, std::size_t sz)
Register a new allocation.
Definition MemoryTracker.hpp:75
void on_free(const void *ptr)
Unregister a freed allocation.
Definition MemoryTracker.hpp:105
Definition MemoryTracker.hpp:13
std::uintptr_t ptr
Definition MemoryTracker.hpp:14
std::size_t size
Definition MemoryTracker.hpp:15
Definition MemoryTracker.hpp:20
bool armed
Definition MemoryTracker.hpp:21
~HookGuard()
Definition MemoryTracker.hpp:25
HookGuard()
Definition MemoryTracker.hpp:22