#ifndef __MEMORYALLOCATIONSTACKTRACER_H__ #define __MEMORYALLOCATIONSTACKTRACER_H__ #include #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>; using String = std::basic_string, DebugAllocator>; using OutStringStream = std::basic_ostringstream, DebugAllocator>; class Infomation { public: std::chrono::system_clock::time_point time; Frame frame; }; ~MemoryAllocationStackTracer(); static MemoryAllocationStackTracer *instance(); inline bool enabled() const { return m_enabled; } template void start(const std::string &path, const std::string &applicationName, const std::chrono::duration &intervals) { if (m_exit) { m_exit = false; m_thread = std::thread(&MemoryAllocationStackTracer::run, this); } m_intervals = std::chrono::duration_cast(intervals); if (!m_enabled) { m_enabled = true; } m_path = path; m_applicationName = applicationName; } void stop(); std::string dump(); void push(uint64_t address, Frame &&stacktrace); void pop(uint64_t address); protected: void run(); private: std::unordered_map, std::equal_to, DebugAllocator>> m_stacktraces; std::unordered_map, std::equal_to, DebugAllocator>> m_counts; static MemoryAllocationStackTracer *m_instance; std::string m_path; std::string m_applicationName; bool m_exit = true; std::thread m_thread; std::chrono::milliseconds m_intervals; bool m_enabled = false; }; #endif // __MEMORYALLOCATIONSTACKTRACER_H__