From 8b3bd5b4b9815db160b011e9d514bfd28c40b78c Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 7 Jun 2015 15:13:41 +0800 Subject: [PATCH] add srs memory watcher. --- trunk/configure | 2 +- trunk/ide/srs_upp/srs_upp.upp | 2 + trunk/ide/srs_vs2010/srs.vcxproj | 2 + .../srs_xcode.xcodeproj/project.pbxproj | 6 ++ trunk/src/app/srs_app_server.cpp | 12 +++ trunk/src/core/srs_core_mem_watch.cpp | 85 +++++++++++++++++++ trunk/src/core/srs_core_mem_watch.hpp | 49 +++++++++++ trunk/src/core/srs_core_performance.hpp | 7 ++ trunk/src/kernel/srs_kernel_flv.cpp | 7 ++ trunk/src/protocol/srs_protocol_buffer.cpp | 2 +- trunk/src/protocol/srs_rtmp_stack.cpp | 7 +- 11 files changed, 178 insertions(+), 3 deletions(-) create mode 100644 trunk/src/core/srs_core_mem_watch.cpp create mode 100644 trunk/src/core/srs_core_mem_watch.hpp diff --git a/trunk/configure b/trunk/configure index c234a810f..57444e793 100755 --- a/trunk/configure +++ b/trunk/configure @@ -138,7 +138,7 @@ if [ $SRS_MIPS_UBUNTU12 = YES ]; then SrsLinkOptions="${SrsLinkOptions} -lgcc_eh MODULE_ID="CORE" MODULE_DEPENDS=() ModuleLibIncs=(${SRS_OBJS_DIR}) -MODULE_FILES=("srs_core" "srs_core_autofree" "srs_core_performance") +MODULE_FILES=("srs_core" "srs_core_autofree" "srs_core_performance" "srs_core_mem_watch") CORE_INCS="src/core"; MODULE_DIR=${CORE_INCS} . auto/modules.sh CORE_OBJS="${MODULE_OBJS[@]}" # diff --git a/trunk/ide/srs_upp/srs_upp.upp b/trunk/ide/srs_upp/srs_upp.upp index 764b0ee0b..e80292576 100755 --- a/trunk/ide/srs_upp/srs_upp.upp +++ b/trunk/ide/srs_upp/srs_upp.upp @@ -16,6 +16,8 @@ file ../../src/core/srs_core.cpp, ../../src/core/srs_core_autofree.hpp, ../../src/core/srs_core_autofree.cpp, + ../../src/core/srs_core_mem_watch.hpp, + ../../src/core/srs_core_mem_watch.cpp, ../../src/core/srs_core_performance.hpp, ../../src/core/srs_core_performance.cpp, kernel readonly separator, diff --git a/trunk/ide/srs_vs2010/srs.vcxproj b/trunk/ide/srs_vs2010/srs.vcxproj index de224841c..5ddd7892f 100755 --- a/trunk/ide/srs_vs2010/srs.vcxproj +++ b/trunk/ide/srs_vs2010/srs.vcxproj @@ -100,6 +100,7 @@ + @@ -181,6 +182,7 @@ + diff --git a/trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj b/trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj index 08f2ecc7f..a6fbb1079 100644 --- a/trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj +++ b/trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj @@ -79,6 +79,7 @@ 3C36DB5B1ABD1CB90066CCAF /* srs_lib_bandwidth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C36DB551ABD1CB90066CCAF /* srs_lib_bandwidth.cpp */; }; 3C36DB5C1ABD1CB90066CCAF /* srs_lib_simple_socket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C36DB571ABD1CB90066CCAF /* srs_lib_simple_socket.cpp */; }; 3C36DB5D1ABD1CB90066CCAF /* srs_librtmp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C36DB591ABD1CB90066CCAF /* srs_librtmp.cpp */; }; + 3C5265B41B241BF0009CA186 /* srs_core_mem_watch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C5265B21B241BF0009CA186 /* srs_core_mem_watch.cpp */; }; 3C663F0F1AB0155100286D8B /* srs_aac_raw_publish.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F021AB0155100286D8B /* srs_aac_raw_publish.c */; }; 3C663F101AB0155100286D8B /* srs_audio_raw_publish.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F031AB0155100286D8B /* srs_audio_raw_publish.c */; }; 3C663F111AB0155100286D8B /* srs_bandwidth_check.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C663F041AB0155100286D8B /* srs_bandwidth_check.c */; }; @@ -327,6 +328,8 @@ 3C36DB581ABD1CB90066CCAF /* srs_lib_simple_socket.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_lib_simple_socket.hpp; path = ../../../src/libs/srs_lib_simple_socket.hpp; sourceTree = ""; }; 3C36DB591ABD1CB90066CCAF /* srs_librtmp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_librtmp.cpp; path = ../../../src/libs/srs_librtmp.cpp; sourceTree = ""; }; 3C36DB5A1ABD1CB90066CCAF /* srs_librtmp.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_librtmp.hpp; path = ../../../src/libs/srs_librtmp.hpp; sourceTree = ""; }; + 3C5265B21B241BF0009CA186 /* srs_core_mem_watch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_core_mem_watch.cpp; path = ../../../src/core/srs_core_mem_watch.cpp; sourceTree = ""; }; + 3C5265B31B241BF0009CA186 /* srs_core_mem_watch.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_core_mem_watch.hpp; path = ../../../src/core/srs_core_mem_watch.hpp; sourceTree = ""; }; 3C663F021AB0155100286D8B /* srs_aac_raw_publish.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_aac_raw_publish.c; path = ../../../research/librtmp/srs_aac_raw_publish.c; sourceTree = ""; }; 3C663F031AB0155100286D8B /* srs_audio_raw_publish.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_audio_raw_publish.c; path = ../../../research/librtmp/srs_audio_raw_publish.c; sourceTree = ""; }; 3C663F041AB0155100286D8B /* srs_bandwidth_check.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = srs_bandwidth_check.c; path = ../../../research/librtmp/srs_bandwidth_check.c; sourceTree = ""; }; @@ -428,6 +431,8 @@ children = ( 3C1231F01AAE652C00CE8F6C /* srs_core_autofree.cpp */, 3C1231F11AAE652C00CE8F6C /* srs_core_autofree.hpp */, + 3C5265B21B241BF0009CA186 /* srs_core_mem_watch.cpp */, + 3C5265B31B241BF0009CA186 /* srs_core_mem_watch.hpp */, 3C1231F21AAE652C00CE8F6C /* srs_core_performance.cpp */, 3C1231F31AAE652C00CE8F6C /* srs_core_performance.hpp */, 3C1231F41AAE652D00CE8F6C /* srs_core.cpp */, @@ -882,6 +887,7 @@ 3CC52DDC1ACE4023006FEB01 /* srs_utest_protocol.cpp in Sources */, 3C663F151AB0155100286D8B /* srs_h264_raw_publish.c in Sources */, 3C1231F61AAE652D00CE8F6C /* srs_core_autofree.cpp in Sources */, + 3C5265B41B241BF0009CA186 /* srs_core_mem_watch.cpp in Sources */, 3C1EE6D71AB1367D00576EE9 /* README.md in Sources */, 3C1232411AAE81A400CE8F6C /* srs_raw_avc.cpp in Sources */, 3C1232491AAE81A400CE8F6C /* srs_rtmp_utility.cpp in Sources */, diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp index 88c8c4b75..d1c64b50b 100644 --- a/trunk/src/app/srs_app_server.cpp +++ b/trunk/src/app/srs_app_server.cpp @@ -47,6 +47,7 @@ using namespace std; #include #include #include +#include // signal defines. #define SIGNAL_RELOAD SIGHUP @@ -556,6 +557,10 @@ void SrsServer::destroy() // @remark never destroy the source, // when we free all sources, the fmle publish may retry // and segment fault. + +#ifdef SRS_MEM_WATCH + srs_memory_report(); +#endif } void SrsServer::dispose() @@ -571,6 +576,10 @@ void SrsServer::dispose() srs_trace("gracefully dispose sources"); srs_trace("terminate server"); + +#ifdef SRS_MEM_WATCH + srs_memory_report(); +#endif } int SrsServer::initialize(ISrsServerCycle* cycle_handler) @@ -891,6 +900,9 @@ void SrsServer::on_signal(int signo) signal_gmc_stop = true; #else srs_trace("user terminate program"); +#ifdef SRS_MEM_WATCH + srs_memory_report(); +#endif exit(0); #endif return; diff --git a/trunk/src/core/srs_core_mem_watch.cpp b/trunk/src/core/srs_core_mem_watch.cpp new file mode 100644 index 000000000..adfb69356 --- /dev/null +++ b/trunk/src/core/srs_core_mem_watch.cpp @@ -0,0 +1,85 @@ +/* +The MIT License (MIT) + +Copyright (c) 2013-2015 SRS(simple-rtmp-server) + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include + +#ifdef SRS_MEM_WATCH + +#include +#include +using namespace std; + +struct SrsMemoryObject +{ + void* ptr; + std::string category; + int size; +}; + +std::map _srs_ptrs; + +void srs_memory_watch(void* ptr, string category, int size) +{ + SrsMemoryObject* obj = NULL; + + std::map::iterator it; + if ((it = _srs_ptrs.find(ptr)) != _srs_ptrs.end()) { + obj = it->second; + } else { + obj = new SrsMemoryObject(); + _srs_ptrs[ptr] = obj; + } + + obj->ptr = ptr; + obj->category = category; + obj->size = size; +} + +void srs_memory_unwatch(void* ptr) +{ + std::map::iterator it; + if ((it = _srs_ptrs.find(ptr)) != _srs_ptrs.end()) { + SrsMemoryObject* obj = it->second; + srs_freep(obj); + + _srs_ptrs.erase(it); + } +} + +void srs_memory_report() +{ + printf("srs memory leak report:\n"); + + int total = 0; + std::map::iterator it; + for (it = _srs_ptrs.begin(); it != _srs_ptrs.end(); ++it) { + SrsMemoryObject* obj = it->second; + printf(" %s: %#"PRIx64", %dKB\n", obj->category.c_str(), (int64_t)obj->ptr, obj->size / 1000); + total += obj->size; + } + + printf("%d objects leak %dKB.\n", (int)_srs_ptrs.size(), total / 1024); +} + +#endif + diff --git a/trunk/src/core/srs_core_mem_watch.hpp b/trunk/src/core/srs_core_mem_watch.hpp new file mode 100644 index 000000000..bcaf96304 --- /dev/null +++ b/trunk/src/core/srs_core_mem_watch.hpp @@ -0,0 +1,49 @@ +/* +The MIT License (MIT) + +Copyright (c) 2013-2015 SRS(simple-rtmp-server) + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef SRS_CORE_MEM_WATCH_HPP +#define SRS_CORE_MEM_WATCH_HPP + +/* +#include +*/ + +#include + +#ifdef SRS_MEM_WATCH + +#include + +// watch the specified memory. +extern void srs_memory_watch(void* ptr, std::string category, int size); + +// unwatch the specified memory. +extern void srs_memory_unwatch(void* ptr); + +// report the memory watch. +extern void srs_memory_report(); + +#endif + +#endif + diff --git a/trunk/src/core/srs_core_performance.hpp b/trunk/src/core/srs_core_performance.hpp index 407ca0fef..c1b924756 100644 --- a/trunk/src/core/srs_core_performance.hpp +++ b/trunk/src/core/srs_core_performance.hpp @@ -188,5 +188,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #undef SRS_PERF_FAST_FLV_ENCODER #define SRS_PERF_FAST_FLV_ENCODER +/** + * whether enable the special memory watcher. + * which used for memory leak debug and hurts performance. + */ +#define SRS_MEM_WATCH +#undef SRS_MEM_WATCH + #endif diff --git a/trunk/src/kernel/srs_kernel_flv.cpp b/trunk/src/kernel/srs_kernel_flv.cpp index 745b5b083..60bd3cfcc 100644 --- a/trunk/src/kernel/srs_kernel_flv.cpp +++ b/trunk/src/kernel/srs_kernel_flv.cpp @@ -38,6 +38,7 @@ using namespace std; #include #include #include +#include SrsMessageHeader::SrsMessageHeader() { @@ -159,6 +160,9 @@ SrsCommonMessage::SrsCommonMessage() SrsCommonMessage::~SrsCommonMessage() { +#ifdef SRS_MEM_WATCH + srs_memory_unwatch(payload); +#endif srs_freep(payload); } @@ -171,6 +175,9 @@ SrsSharedPtrMessage::SrsSharedPtrPayload::SrsSharedPtrPayload() SrsSharedPtrMessage::SrsSharedPtrPayload::~SrsSharedPtrPayload() { +#ifdef SRS_MEM_WATCH + srs_memory_unwatch(payload); +#endif srs_freep(payload); } diff --git a/trunk/src/protocol/srs_protocol_buffer.cpp b/trunk/src/protocol/srs_protocol_buffer.cpp index 176131282..9efa26d78 100644 --- a/trunk/src/protocol/srs_protocol_buffer.cpp +++ b/trunk/src/protocol/srs_protocol_buffer.cpp @@ -72,7 +72,7 @@ SrsFastBuffer::~SrsFastBuffer() int SrsFastBuffer::size() { - return end - p; + return (int)(end - p); } char* SrsFastBuffer::bytes() diff --git a/trunk/src/protocol/srs_rtmp_stack.cpp b/trunk/src/protocol/srs_rtmp_stack.cpp index 738a7d81f..b4893955a 100644 --- a/trunk/src/protocol/srs_rtmp_stack.cpp +++ b/trunk/src/protocol/srs_rtmp_stack.cpp @@ -30,6 +30,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include #include +#include // for srs-librtmp, @see https://github.com/simple-rtmp-server/srs/issues/213 #ifndef _WIN32 @@ -364,6 +365,7 @@ int SrsProtocol::recv_message(SrsCommonMessage** pmsg) srs_verbose("entire msg received"); if (!msg) { + srs_info("got empty message without error."); continue; } @@ -467,7 +469,7 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs) iovs[0].iov_len = nbh; // payload iov - int payload_size = srs_min(out_chunk_size, pend - p); + int payload_size = srs_min(out_chunk_size, (int)(pend - p)); iovs[1].iov_base = p; iovs[1].iov_len = payload_size; @@ -1411,6 +1413,9 @@ int SrsProtocol::read_message_payload(SrsChunkStream* chunk, SrsCommonMessage** if (!chunk->msg->payload) { chunk->msg->payload = new char[chunk->header.payload_length]; srs_verbose("create payload for RTMP message. size=%d", chunk->header.payload_length); +#ifdef SRS_MEM_WATCH + srs_memory_watch(chunk->msg->payload, "msg.payload", chunk->header.payload_length); +#endif } // read payload to buffer