add memory leak test code.

This commit is contained in:
luocai 2024-03-23 11:57:23 +08:00
parent b1396e75ec
commit 4178f405f2
10 changed files with 272 additions and 1 deletions

1
.gitignore vendored
View File

@ -38,4 +38,5 @@ target_wrapper.*
# QtCreator CMake # QtCreator CMake
CMakeLists.txt.user* CMakeLists.txt.user*
.idea
build build

View File

@ -7,6 +7,7 @@
"${workspaceFolder}/3rdparty/ds_pedestrian_mot_hisi/include", "${workspaceFolder}/3rdparty/ds_pedestrian_mot_hisi/include",
"/opt/Libraries/boost_1_84_0/include", "/opt/Libraries/boost_1_84_0/include",
"/opt/aarch64-v01c01-linux-gnu-gcc/lib/ZLMediaKit/include", "/opt/aarch64-v01c01-linux-gnu-gcc/lib/ZLMediaKit/include",
"/opt/aarch64-v01c01-linux-gnu-gcc/lib/LeakTracer/include",
"build/_deps/kylin-src/Universal" "build/_deps/kylin-src/Universal"
], ],
"defines": [], "defines": [],

View File

@ -1 +1,2 @@
add_subdirectory(LeakTracer)
add_subdirectory(VideoRecoder) add_subdirectory(VideoRecoder)

View File

@ -0,0 +1,18 @@
add_executable(LeakTracer main.cpp
# LeakTracer.h LeakTracer.cpp
MemoryAllocationStackTracer.h MemoryAllocationStackTracer.cpp
)
target_include_directories(LeakTracer
PRIVATE ${Libraries_ROOT}/LeakTracer/include
)
target_link_directories(LeakTracer
PRIVATE ${Libraries_ROOT}/LeakTracer
)
target_link_libraries(LeakTracer
PUBLIC Universal
-Wl,--wrap=malloc
-Wl,--wrap=free
)

View File

@ -0,0 +1,39 @@
#include "LeakTracer.h"
#include "DateTime.h"
#include <leaktracer.h>
#include <sstream>
LeakTracer::LeakTracer(const std::string &path, const std::string &applicationName)
: m_path(path), m_applicationName(applicationName) {
}
LeakTracer::~LeakTracer() {
stop();
}
void LeakTracer::run() {
using namespace std::chrono;
using namespace std::chrono_literals;
while (!m_exit) {
auto start = system_clock::now();
leaktracer_startMonitoringAllThreads();
while (!m_exit) {
std::this_thread::sleep_for(50ms);
auto now = system_clock::now();
auto elapsed = duration_cast<milliseconds>(now - start);
if (elapsed >= m_intervals) break;
}
std::ostringstream oss;
oss << m_path << "/" << m_applicationName << "_" << DateTime(start).toString("%Y%m%d%H%M%S") << "-"
<< DateTime::currentDateTime().toString("%Y%m%d%H%M%S") << ".dump";
leaktracer_writeLeaksToFile(oss.str().c_str());
leaktracer_stopAllMonitoring();
}
}
void LeakTracer::stop() {
if (!m_exit) {
m_exit = true;
if (m_thread.joinable()) m_thread.join();
}
}

View File

@ -0,0 +1,34 @@
#ifndef __AMASS_LEAKTRACER_H__
#define __AMASS_LEAKTRACER_H__
#include <chrono>
#include <string>
#include <thread>
class LeakTracer {
public:
LeakTracer(const std::string &path, const std::string &applicationName);
~LeakTracer();
template <class Rep, class Period>
void start(const std::chrono::duration<Rep, Period> &intervals) {
if (m_exit) {
m_exit = false;
m_thread = std::thread(&LeakTracer::run, this);
}
m_intervals = std::chrono::duration_cast<std::chrono::milliseconds>(intervals);
}
void stop();
protected:
void run();
private:
bool m_exit = true;
std::string m_path;
std::string m_applicationName;
std::chrono::milliseconds m_intervals;
std::thread m_thread;
};
#endif // __AMASS_LEAKTRACER_H__

View File

@ -0,0 +1,63 @@
#include "MemoryAllocationStackTracer.h"
#include <iostream>
#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;
return address;
}
void __wrap_free(void *__ptr) {
// if (__ptr != nullptr) {
// MemoryAllocationStackTracer::instance()->pop(reinterpret_cast<uint64_t>(__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);
// if (size != sizeof(boost::stacktrace::stacktrace) || size != 2048) {
// MemoryAllocationStackTracer::instance()->push(reinterpret_cast<uint64_t>(address),
// boost::stacktrace::stacktrace());
// }
return address;
}
void operator delete(void *p) {
free(p);
}
MemoryAllocationStackTracer *MemoryAllocationStackTracer::m_instance = nullptr;
void MemoryAllocationStackTracer::initialize() {
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;
}

View File

@ -0,0 +1,76 @@
#ifndef __MEMORYALLOCATIONSTACKTRACER_H__
#define __MEMORYALLOCATIONSTACKTRACER_H__
#include <boost/stacktrace/stacktrace.hpp>
#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) {
return reinterpret_cast<T *>(__real_malloc(n));
}
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:
static void initialize();
static MemoryAllocationStackTracer *instance();
void push(uint64_t address, const boost::stacktrace::stacktrace &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>>
m_stacktraces;
static MemoryAllocationStackTracer *m_instance;
};
#endif // __MEMORYALLOCATIONSTACKTRACER_H__

37
Tools/LeakTracer/main.cpp Normal file
View File

@ -0,0 +1,37 @@
#include "LeakTracer.h"
#include "MemoryAllocationStackTracer.h"
#include <boost/stacktrace.hpp>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void test() {
std::cout << boost::stacktrace::stacktrace();
malloc(20);
}
int make_memory_leak(void) {
printf("%s:%d, 00!\n", __FILE__, __LINE__);
int *ptr = (int *)malloc(sizeof(int)); // 分配内存块
*ptr = 0; // 构造内存泄露
printf("%s:%d, ptr= %p, *ptr= %d!\n", __FILE__, __LINE__, ptr, *ptr);
char *p_new = new char[8 * 1024 * 1024];
(void)memset(p_new, 0, 8 * 1024 * 1024);
*p_new = 0;
printf("%s:%d, p_new= %p, *p_new= %d!\n", __FILE__, __LINE__, p_new, *p_new);
return 0;
}
class Test {
int a;
};
int main(int argc, char const *argv[]) {
MemoryAllocationStackTracer::initialize();
auto a = new Test();
return 0;
}

View File

@ -62,6 +62,7 @@ function init() {
echo "put /opt/aarch64-v01c01-linux-gnu-gcc/lib/gdb-10.2/bin/gdbserver /system/bin" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP} echo "put /opt/aarch64-v01c01-linux-gnu-gcc/lib/gdb-10.2/bin/gdbserver /system/bin" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
ssh -i resources/ssh_host_rsa_key_ok root@${TARGET_IP} "mkdir -p /data/sdcard/PassengerStatistics/lib" ssh -i resources/ssh_host_rsa_key_ok root@${TARGET_IP} "mkdir -p /data/sdcard/PassengerStatistics/lib"
echo "put /opt/aarch64-v01c01-linux-gnu-gcc/lib/ZLMediaKit/lib/libmk_api.so /data/sdcard/PassengerStatistics/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP} echo "put /opt/aarch64-v01c01-linux-gnu-gcc/lib/ZLMediaKit/lib/libmk_api.so /data/sdcard/PassengerStatistics/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
echo "put /opt/aarch64-v01c01-linux-gnu-gcc/lib/LeakTracer/libleaktracer.so /data/sdcard/PassengerStatistics/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
# echo "put ${BOOST_LIBDIR}/libboost_date_time* /system/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP} # echo "put ${BOOST_LIBDIR}/libboost_date_time* /system/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
echo "put ${BOOST_LIBDIR}/libboost_regex.so.1.84.0 /system/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP} echo "put ${BOOST_LIBDIR}/libboost_regex.so.1.84.0 /system/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
echo "put ${BOOST_LIBDIR}/libboost_log_setup.so.1.84.0 /system/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP} echo "put ${BOOST_LIBDIR}/libboost_log_setup.so.1.84.0 /system/lib" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
@ -87,7 +88,7 @@ function deploy() {
echo "deploy to target $TARGET_IP, path: ${TARGET_PATH} ..." echo "deploy to target $TARGET_IP, path: ${TARGET_PATH} ..."
echo "put ${build_path}/Main/PassengerStatistics ${TARGET_PATH}" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP} echo "put ${build_path}/Main/PassengerStatistics ${TARGET_PATH}" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
echo "put ${build_path}/Tools/VideoRecoder/VideoRecoder ${TARGET_PATH}" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP} echo "put ${build_path}/Tools/VideoRecoder/VideoRecoder ${TARGET_PATH}" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
echo "put ${build_path}/Tools/LeakTracer/LeakTracer ${TARGET_PATH}" | sftp -i resources/ssh_host_rsa_key_ok root@${TARGET_IP}
ssh -i resources/ssh_host_rsa_key_ok root@${TARGET_IP} "sync" ssh -i resources/ssh_host_rsa_key_ok root@${TARGET_IP} "sync"
} }