2024-03-23 11:57:23 +08:00
|
|
|
#ifndef __MEMORYALLOCATIONSTACKTRACER_H__
|
|
|
|
#define __MEMORYALLOCATIONSTACKTRACER_H__
|
|
|
|
|
|
|
|
#include <boost/stacktrace/stacktrace.hpp>
|
2024-03-25 00:09:33 +08:00
|
|
|
#include <chrono>
|
2024-03-23 11:57:23 +08:00
|
|
|
#include <unordered_map>
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
extern void *__real_malloc(size_t size);
|
|
|
|
extern void __real_free(void *__ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class T>
|
|
|
|
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 <class U>
|
|
|
|
struct rebind {
|
|
|
|
typedef DebugAllocator<U> other;
|
|
|
|
};
|
|
|
|
DebugAllocator() {
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class U>
|
|
|
|
DebugAllocator(const DebugAllocator<U> &other) noexcept {
|
|
|
|
}
|
|
|
|
|
|
|
|
T *allocate(std::size_t n) {
|
2024-03-25 00:09:33 +08:00
|
|
|
return reinterpret_cast<T *>(__real_malloc(n * sizeof(T)));
|
2024-03-23 11:57:23 +08:00
|
|
|
}
|
|
|
|
void deallocate(T *p, std::size_t n) {
|
|
|
|
__real_free(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class U, class... Args>
|
|
|
|
void construct(U *p, Args &&...args) {
|
|
|
|
::new ((void *)p) U(std::forward<Args>(args)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class U>
|
|
|
|
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:
|
2024-03-25 00:09:33 +08:00
|
|
|
using Frame = boost::stacktrace::basic_stacktrace<DebugAllocator<boost::stacktrace::frame>>;
|
|
|
|
class Infomation {
|
|
|
|
public:
|
|
|
|
std::chrono::system_clock::time_point time;
|
|
|
|
Frame frame;
|
|
|
|
};
|
2024-03-23 11:57:23 +08:00
|
|
|
static MemoryAllocationStackTracer *instance();
|
2024-03-25 00:09:33 +08:00
|
|
|
inline bool enabled() const {
|
|
|
|
return m_enabled;
|
|
|
|
}
|
|
|
|
void start();
|
|
|
|
void dump();
|
|
|
|
void push(uint64_t address, Frame &&stacktrace);
|
2024-03-23 11:57:23 +08:00
|
|
|
void pop(uint64_t address);
|
|
|
|
|
|
|
|
private:
|
2024-03-25 00:09:33 +08:00
|
|
|
std::unordered_map<uint64_t, Infomation, std::hash<uint64_t>, std::equal_to<uint64_t>,
|
|
|
|
DebugAllocator<std::pair<const uint64_t, Infomation>>>
|
2024-03-23 11:57:23 +08:00
|
|
|
m_stacktraces;
|
|
|
|
|
|
|
|
static MemoryAllocationStackTracer *m_instance;
|
2024-03-25 00:09:33 +08:00
|
|
|
bool m_enabled = false;
|
2024-03-23 11:57:23 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // __MEMORYALLOCATIONSTACKTRACER_H__
|