mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-22 19:00:01 +08:00
添加全局内存统计功能
This commit is contained in:
parent
a19f67679a
commit
0c728827aa
@ -53,6 +53,21 @@ option(ENABLE_API "Enable C API SDK" true)
|
|||||||
option(ENABLE_CXX_API "Enable C++ API SDK" false)
|
option(ENABLE_CXX_API "Enable C++ API SDK" false)
|
||||||
option(ENABLE_TESTS "Enable Tests" true)
|
option(ENABLE_TESTS "Enable Tests" true)
|
||||||
option(ENABLE_SERVER "Enable Server" true)
|
option(ENABLE_SERVER "Enable Server" true)
|
||||||
|
option(ENABLE_MEM_DEBUG "Enable Memory Debug" false)
|
||||||
|
option(ENABLE_ASAN "Enable Address Sanitize" false)
|
||||||
|
|
||||||
|
if (ENABLE_MEM_DEBUG)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,-wrap,free -Wl,-wrap,malloc -Wl,-wrap,realloc -Wl,-wrap,calloc")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-wrap,free -Wl,-wrap,malloc -Wl,-wrap,realloc -Wl,-wrap,calloc")
|
||||||
|
add_definitions(-DENABLE_MEM_DEBUG)
|
||||||
|
message(STATUS "已启用内存调试功能")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (ENABLE_ASAN)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer")
|
||||||
|
message(STATUS "已启用Address Sanitize")
|
||||||
|
endif ()
|
||||||
|
|
||||||
set(LINK_LIB_LIST zlmediakit zltoolkit)
|
set(LINK_LIB_LIST zlmediakit zltoolkit)
|
||||||
|
|
||||||
|
@ -170,6 +170,8 @@ static ApiArgsType getAllArgs(const Parser &parser) {
|
|||||||
return allArgs;
|
return allArgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern uint64_t getTotalMemUsage();
|
||||||
|
|
||||||
static inline void addHttpListener(){
|
static inline void addHttpListener(){
|
||||||
GET_CONFIG(bool, api_debug, API::kApiDebug);
|
GET_CONFIG(bool, api_debug, API::kApiDebug);
|
||||||
//注册监听kBroadcastHttpRequest事件
|
//注册监听kBroadcastHttpRequest事件
|
||||||
@ -1046,6 +1048,11 @@ void installWebApi() {
|
|||||||
|
|
||||||
val["data"]["RtpPacket"] = (Json::UInt64)(ObjectStatistic<RtpPacket>::count());
|
val["data"]["RtpPacket"] = (Json::UInt64)(ObjectStatistic<RtpPacket>::count());
|
||||||
val["data"]["RtmpPacket"] = (Json::UInt64)(ObjectStatistic<RtmpPacket>::count());
|
val["data"]["RtmpPacket"] = (Json::UInt64)(ObjectStatistic<RtmpPacket>::count());
|
||||||
|
#ifdef ENABLE_MEM_DEBUG
|
||||||
|
auto bytes = getTotalMemUsage();
|
||||||
|
val["data"]["totalMemUsage"] = (Json::UInt64)bytes;
|
||||||
|
val["data"]["totalMemUsageMB"] = (int)(bytes / 1024 / 1024);
|
||||||
|
#endif
|
||||||
});
|
});
|
||||||
|
|
||||||
////////////以下是注册的Hook API////////////
|
////////////以下是注册的Hook API////////////
|
||||||
|
@ -307,11 +307,117 @@ const string kBenchmarkMode = "benchmark_mode";
|
|||||||
|
|
||||||
} // namespace mediakit
|
} // namespace mediakit
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
void Assert_Throw(int failed, const char *exp, const char *func, const char *file, int line){
|
void Assert_Throw(int failed, const char *exp, const char *func, const char *file, int line) {
|
||||||
if(failed) {
|
if (failed) {
|
||||||
_StrPrinter printer;
|
_StrPrinter printer;
|
||||||
printer << "Assertion failed: (" << exp << "), function " << func << ", file " << file << ", line " << line << ".";
|
printer << "Assertion failed: (" << exp << "), function " << func << ", file " << file << ", line " << line
|
||||||
|
<< ".";
|
||||||
throw std::runtime_error(printer);
|
throw std::runtime_error(printer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_MEM_DEBUG
|
||||||
|
|
||||||
|
static atomic<uint64_t> mem_usage(0);
|
||||||
|
|
||||||
|
uint64_t getTotalMemUsage() {
|
||||||
|
return mem_usage.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#define MAGIC_BYTES 0xFEFDFCFB
|
||||||
|
#define MAGIC_BYTES_SIZE 4
|
||||||
|
#define MEM_PREFIX_SIZE 8
|
||||||
|
|
||||||
|
extern void *__real_malloc(size_t);
|
||||||
|
extern void __real_free(void *);
|
||||||
|
extern void *__real_realloc(void *ptr, size_t c);
|
||||||
|
|
||||||
|
void *__wrap_malloc(size_t c) {
|
||||||
|
c += MEM_PREFIX_SIZE;
|
||||||
|
char *ret = (char *) __real_malloc(c);
|
||||||
|
if (ret) {
|
||||||
|
mem_usage += c;
|
||||||
|
*((uint32_t *) (ret)) = MAGIC_BYTES;
|
||||||
|
*((uint32_t *) (ret + MAGIC_BYTES_SIZE)) = c;
|
||||||
|
return ret + MEM_PREFIX_SIZE;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __wrap_free(void *ptr) {
|
||||||
|
if (!ptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ptr = (char *) ptr - MEM_PREFIX_SIZE;
|
||||||
|
uint32_t magic = *((uint32_t *) (ptr));
|
||||||
|
if (magic != MAGIC_BYTES) {
|
||||||
|
throw std::invalid_argument("attempt to free invalid memory");
|
||||||
|
}
|
||||||
|
mem_usage -= *((uint32_t *) ((char *) ptr + MAGIC_BYTES_SIZE));
|
||||||
|
__real_free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *__wrap_calloc(size_t __nmemb, size_t __size) {
|
||||||
|
auto size = __nmemb * __size;
|
||||||
|
auto ret = malloc(size);
|
||||||
|
if (ret) {
|
||||||
|
memset(ret, 0, size);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *__wrap_realloc(void *ptr, size_t c){
|
||||||
|
if (!ptr) {
|
||||||
|
return malloc(c);
|
||||||
|
}
|
||||||
|
c += MEM_PREFIX_SIZE;
|
||||||
|
ptr = (char *) ptr - MEM_PREFIX_SIZE;
|
||||||
|
|
||||||
|
uint32_t magic = *((uint32_t *) (ptr));
|
||||||
|
if (magic != MAGIC_BYTES) {
|
||||||
|
throw std::invalid_argument("attempt to realloc invalid memory");
|
||||||
|
}
|
||||||
|
auto old_size = *((uint32_t *) ((char *) ptr + MAGIC_BYTES_SIZE));
|
||||||
|
char *ret = (char *) __real_realloc(ptr, c);
|
||||||
|
if (ret) {
|
||||||
|
mem_usage += c - old_size;
|
||||||
|
*((uint32_t *) (ret)) = MAGIC_BYTES;
|
||||||
|
*((uint32_t *) (ret + MAGIC_BYTES_SIZE)) = c;
|
||||||
|
return ret + MEM_PREFIX_SIZE;
|
||||||
|
}
|
||||||
|
free(ptr);
|
||||||
|
mem_usage -= old_size;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void *operator new(std::size_t size) {
|
||||||
|
auto ret = malloc(size);
|
||||||
|
if (ret) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
throw std::bad_alloc();
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator delete(void *ptr) {
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *operator new[](std::size_t size) {
|
||||||
|
auto ret = malloc(size);
|
||||||
|
if (ret) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
throw std::bad_alloc();
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator delete[](void *ptr) {
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user