add test.
This commit is contained in:
parent
4178f405f2
commit
d745f7d8c6
@ -26,7 +26,9 @@ set(ZLMediaKit_ROOT /opt/aarch64-v01c01-linux-gnu-gcc/lib/ZLMediaKit)
|
||||
set(ZLMediaKit_INCLUDE_DIR ${ZLMediaKit_ROOT}/include)
|
||||
set(ZLMediaKit_LIBRARY_DIRS ${ZLMediaKit_ROOT}/lib)
|
||||
|
||||
add_subdirectory(Main)
|
||||
if(${CROSS_BUILD})
|
||||
add_subdirectory(Main)
|
||||
endif()
|
||||
add_subdirectory(Tools)
|
||||
|
||||
include(FetchContent)
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
|
@ -3,6 +3,10 @@ add_executable(LeakTracer main.cpp
|
||||
MemoryAllocationStackTracer.h MemoryAllocationStackTracer.cpp
|
||||
)
|
||||
|
||||
target_compile_definitions(LeakTracer
|
||||
PRIVATE BOOST_STACKTRACE_USE_ADDR2LINE
|
||||
)
|
||||
|
||||
target_include_directories(LeakTracer
|
||||
PRIVATE ${Libraries_ROOT}/LeakTracer/include
|
||||
)
|
||||
|
@ -1,63 +1,98 @@
|
||||
#include "MemoryAllocationStackTracer.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
void *__wrap_malloc(size_t size) {
|
||||
void *address = __real_malloc(size);
|
||||
// if (address != nullptr) {
|
||||
// MemoryAllocationStackTracer::instance()->push(reinterpret_cast<uint64_t>(address),
|
||||
// boost::stacktrace::stacktrace());
|
||||
// }
|
||||
// std::cout << "malloc " << size << " bytes." << std::endl;
|
||||
auto self = MemoryAllocationStackTracer::instance();
|
||||
if (address != nullptr && self->enabled()) {
|
||||
self->push(reinterpret_cast<uint64_t>(address), MemoryAllocationStackTracer::Frame());
|
||||
}
|
||||
// printf("%p = malloc(%zu)\n", address, size);
|
||||
return address;
|
||||
}
|
||||
|
||||
void __wrap_free(void *__ptr) {
|
||||
// if (__ptr != nullptr) {
|
||||
// MemoryAllocationStackTracer::instance()->pop(reinterpret_cast<uint64_t>(__ptr));
|
||||
// }
|
||||
if (__ptr != nullptr) {
|
||||
MemoryAllocationStackTracer::instance()->pop(reinterpret_cast<uint64_t>(__ptr));
|
||||
}
|
||||
// printf("free(%p)\n", __ptr);
|
||||
return __real_free(__ptr);
|
||||
}
|
||||
}
|
||||
|
||||
void *operator new(std::size_t size) {
|
||||
printf("new %d %d\n ", size, sizeof(boost::stacktrace::stacktrace));
|
||||
void *address = __real_malloc(size);
|
||||
// printf("void *operator new(std::size_t size),%zu\n", size);
|
||||
|
||||
// if (size != sizeof(boost::stacktrace::stacktrace) || size != 2048) {
|
||||
// MemoryAllocationStackTracer::instance()->push(reinterpret_cast<uint64_t>(address),
|
||||
// boost::stacktrace::stacktrace());
|
||||
// }
|
||||
|
||||
return address;
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void operator delete(void *p) {
|
||||
free(p);
|
||||
void operator delete(void *p) noexcept {
|
||||
// printf("%s", "void operator delete(void *p)\n");
|
||||
return free(p);
|
||||
}
|
||||
|
||||
void *operator new[](std::size_t count) {
|
||||
// printf("%s", "void *operator new[](std::size_t count)\n");
|
||||
return malloc(count);
|
||||
}
|
||||
|
||||
void operator delete[](void *ptr) noexcept {
|
||||
// printf("%s", "void operator delete[](void *ptr) noexcept\n");
|
||||
return free(ptr);
|
||||
}
|
||||
|
||||
MemoryAllocationStackTracer *MemoryAllocationStackTracer::m_instance = nullptr;
|
||||
|
||||
void MemoryAllocationStackTracer::initialize() {
|
||||
void MemoryAllocationStackTracer::start() {
|
||||
if (!m_enabled) {
|
||||
m_enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryAllocationStackTracer::push(uint64_t address, Frame &&stacktrace) {
|
||||
Infomation info;
|
||||
info.time = std::chrono::system_clock::now();
|
||||
info.frame = std::move(stacktrace);
|
||||
m_stacktraces.insert({address, info});
|
||||
// m_stacktraces.insert({address, stacktrace});
|
||||
}
|
||||
|
||||
void MemoryAllocationStackTracer::pop(uint64_t address) {
|
||||
if (m_stacktraces.count(address) > 0) {
|
||||
m_stacktraces.erase(address);
|
||||
}
|
||||
}
|
||||
|
||||
MemoryAllocationStackTracer *MemoryAllocationStackTracer::instance() {
|
||||
if (m_instance == nullptr) {
|
||||
auto buffer = __real_malloc(sizeof(MemoryAllocationStackTracer));
|
||||
if (buffer != nullptr) {
|
||||
m_instance = new (buffer) MemoryAllocationStackTracer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryAllocationStackTracer::push(uint64_t address, const boost::stacktrace::stacktrace &stacktrace) {
|
||||
m_stacktraces.insert({address, stacktrace});
|
||||
}
|
||||
|
||||
void MemoryAllocationStackTracer::pop(uint64_t address) {
|
||||
m_stacktraces.erase(address);
|
||||
}
|
||||
|
||||
MemoryAllocationStackTracer *MemoryAllocationStackTracer::instance() {
|
||||
|
||||
return m_instance;
|
||||
}
|
||||
void MemoryAllocationStackTracer::dump() {
|
||||
using namespace std::chrono;
|
||||
m_enabled = false;
|
||||
std::cout << "size: " << m_stacktraces.size() << std::endl;
|
||||
int index = 0;
|
||||
auto now = std::chrono::system_clock::now();
|
||||
std::ofstream ofs("test.txt");
|
||||
for (auto &info : m_stacktraces) {
|
||||
std::ostringstream oss;
|
||||
auto duration = duration_cast<seconds>(now - info.second.time);
|
||||
oss << "-----index[" << index << "] duration: " << duration.count() << "s:-----" << std::endl;
|
||||
oss << info.second.frame << std::endl;
|
||||
auto content = oss.str();
|
||||
ofs << content;
|
||||
std::cout << content;
|
||||
index++;
|
||||
}
|
||||
m_enabled = true;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define __MEMORYALLOCATIONSTACKTRACER_H__
|
||||
|
||||
#include <boost/stacktrace/stacktrace.hpp>
|
||||
#include <chrono>
|
||||
#include <unordered_map>
|
||||
|
||||
extern "C" {
|
||||
@ -33,7 +34,7 @@ public:
|
||||
}
|
||||
|
||||
T *allocate(std::size_t n) {
|
||||
return reinterpret_cast<T *>(__real_malloc(n));
|
||||
return reinterpret_cast<T *>(__real_malloc(n * sizeof(T)));
|
||||
}
|
||||
void deallocate(T *p, std::size_t n) {
|
||||
__real_free(p);
|
||||
@ -60,17 +61,28 @@ public:
|
||||
|
||||
class MemoryAllocationStackTracer {
|
||||
public:
|
||||
static void initialize();
|
||||
using Frame = boost::stacktrace::basic_stacktrace<DebugAllocator<boost::stacktrace::frame>>;
|
||||
class Infomation {
|
||||
public:
|
||||
std::chrono::system_clock::time_point time;
|
||||
Frame frame;
|
||||
};
|
||||
static MemoryAllocationStackTracer *instance();
|
||||
void push(uint64_t address, const boost::stacktrace::stacktrace &stacktrace);
|
||||
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<uint64_t, boost::stacktrace::stacktrace, std::hash<uint64_t>, std::equal_to<uint64_t>,
|
||||
DebugAllocator<MemoryAllocationStackTracer>>
|
||||
std::unordered_map<uint64_t, Infomation, std::hash<uint64_t>, std::equal_to<uint64_t>,
|
||||
DebugAllocator<std::pair<const uint64_t, Infomation>>>
|
||||
m_stacktraces;
|
||||
|
||||
static MemoryAllocationStackTracer *m_instance;
|
||||
bool m_enabled = false;
|
||||
};
|
||||
|
||||
#endif // __MEMORYALLOCATIONSTACKTRACER_H__
|
@ -1,3 +1,4 @@
|
||||
#include "BoostLog.h"
|
||||
#include "LeakTracer.h"
|
||||
#include "MemoryAllocationStackTracer.h"
|
||||
#include <boost/stacktrace.hpp>
|
||||
@ -31,7 +32,13 @@ class Test {
|
||||
};
|
||||
|
||||
int main(int argc, char const *argv[]) {
|
||||
MemoryAllocationStackTracer::initialize();
|
||||
LOG(info) << "hello world.";
|
||||
|
||||
MemoryAllocationStackTracer::instance()->start();
|
||||
auto a = new Test();
|
||||
|
||||
make_memory_leak();
|
||||
MemoryAllocationStackTracer::instance()->dump();
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user