#ifndef __MEMORYALLOCATIONSTACKTRACER_H__ #define __MEMORYALLOCATIONSTACKTRACER_H__ #include #include #include extern "C" { extern void *__real_malloc(size_t size); extern void __real_free(void *__ptr); } template class DebugAllocator { public: using value_type = T; using pointer = T *; typedef const T *const_pointer; typedef T &reference; typedef const T &const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; template struct rebind { typedef DebugAllocator other; }; DebugAllocator() { } template DebugAllocator(const DebugAllocator &other) noexcept { } T *allocate(std::size_t n) { return reinterpret_cast(__real_malloc(n * sizeof(T))); } void deallocate(T *p, std::size_t n) { __real_free(p); } template void construct(U *p, Args &&...args) { ::new ((void *)p) U(std::forward(args)...); } template void destroy(U *p) { p->~U(); } pointer address(reference x) { return (pointer)&x; } const_pointer address(const_reference x) { return (const_pointer)&x; } }; class MemoryAllocationStackTracer { public: using Frame = boost::stacktrace::basic_stacktrace>; class Infomation { public: std::chrono::system_clock::time_point time; Frame frame; }; static MemoryAllocationStackTracer *instance(); inline bool enabled() const { return m_enabled; } void start(); void dump(); void push(uint64_t address, Frame &&stacktrace); void pop(uint64_t address); private: std::unordered_map, std::equal_to, DebugAllocator>> m_stacktraces; static MemoryAllocationStackTracer *m_instance; bool m_enabled = false; }; #endif // __MEMORYALLOCATIONSTACKTRACER_H__