diff --git a/CMakeLists.txt b/CMakeLists.txt index 0735509..767679c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/Main/VideoInput.h b/Main/VideoInput.h index 1e0f77e..ce5ee23 100644 --- a/Main/VideoInput.h +++ b/Main/VideoInput.h @@ -3,6 +3,7 @@ #include #include +#include #include #include diff --git a/Tools/LeakTracer/CMakeLists.txt b/Tools/LeakTracer/CMakeLists.txt index 4378822..2d5c24b 100644 --- a/Tools/LeakTracer/CMakeLists.txt +++ b/Tools/LeakTracer/CMakeLists.txt @@ -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 ) diff --git a/Tools/LeakTracer/MemoryAllocationStackTracer.cpp b/Tools/LeakTracer/MemoryAllocationStackTracer.cpp index 69a4dcf..b906751 100644 --- a/Tools/LeakTracer/MemoryAllocationStackTracer.cpp +++ b/Tools/LeakTracer/MemoryAllocationStackTracer.cpp @@ -1,63 +1,98 @@ #include "MemoryAllocationStackTracer.h" +#include #include +#include #include extern "C" { void *__wrap_malloc(size_t size) { void *address = __real_malloc(size); - // if (address != nullptr) { - // MemoryAllocationStackTracer::instance()->push(reinterpret_cast(address), - // boost::stacktrace::stacktrace()); - // } - // std::cout << "malloc " << size << " bytes." << std::endl; + auto self = MemoryAllocationStackTracer::instance(); + if (address != nullptr && self->enabled()) { + self->push(reinterpret_cast(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(__ptr)); - // } + if (__ptr != nullptr) { + MemoryAllocationStackTracer::instance()->pop(reinterpret_cast(__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(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(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; +} diff --git a/Tools/LeakTracer/MemoryAllocationStackTracer.h b/Tools/LeakTracer/MemoryAllocationStackTracer.h index 0372324..4985542 100644 --- a/Tools/LeakTracer/MemoryAllocationStackTracer.h +++ b/Tools/LeakTracer/MemoryAllocationStackTracer.h @@ -2,6 +2,7 @@ #define __MEMORYALLOCATIONSTACKTRACER_H__ #include +#include #include extern "C" { @@ -33,7 +34,7 @@ public: } T *allocate(std::size_t n) { - return reinterpret_cast(__real_malloc(n)); + return reinterpret_cast(__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>; + 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, std::equal_to, - DebugAllocator> + std::unordered_map, std::equal_to, + DebugAllocator>> m_stacktraces; static MemoryAllocationStackTracer *m_instance; + bool m_enabled = false; }; #endif // __MEMORYALLOCATIONSTACKTRACER_H__ \ No newline at end of file diff --git a/Tools/LeakTracer/main.cpp b/Tools/LeakTracer/main.cpp index fb93472..6f5d33b 100644 --- a/Tools/LeakTracer/main.cpp +++ b/Tools/LeakTracer/main.cpp @@ -1,3 +1,4 @@ +#include "BoostLog.h" #include "LeakTracer.h" #include "MemoryAllocationStackTracer.h" #include @@ -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; -} +} \ No newline at end of file