winlin

add gperf to heap check, use reload signal to terminate program normally

@@ -448,3 +448,15 @@ if [ $SRS_GPERF = YES ]; then @@ -448,3 +448,15 @@ if [ $SRS_GPERF = YES ]; then
448 ret=$?; if [[ $ret -ne 0 ]]; then echo "build gperftools-2.1 failed, ret=$ret"; exit $ret; fi 448 ret=$?; if [[ $ret -ne 0 ]]; then echo "build gperftools-2.1 failed, ret=$ret"; exit $ret; fi
449 if [ ! -f ${SRS_OBJS}/gperf/bin/pprof ]; then echo "build gperftools-2.1 failed."; exit -1; fi 449 if [ ! -f ${SRS_OBJS}/gperf/bin/pprof ]; then echo "build gperftools-2.1 failed."; exit -1; fi
450 fi 450 fi
  451 +
  452 +if [ $SRS_GPERF = YES ]; then
  453 + echo "#define SRS_GPERF" >> $SRS_AUTO_HEADERS_H
  454 + #echo "#define SRS_GPERF_CPU_PROFILE" >> $SRS_AUTO_HEADERS_H
  455 + #echo "#define SRS_GPERF_HEAP_PROFILE" >> $SRS_AUTO_HEADERS_H
  456 + echo "#define SRS_GPERF_HEAP_CHECK" >> $SRS_AUTO_HEADERS_H
  457 +else
  458 + echo "#undef SRS_GPERF" >> $SRS_AUTO_HEADERS_H
  459 + echo "#undef SRS_GPERF_CPU_PROFILE" >> $SRS_AUTO_HEADERS_H
  460 + echo "#undef SRS_GPERF_HEAP_PROFILE" >> $SRS_AUTO_HEADERS_H
  461 + echo "#undef SRS_GPERF_HEAP_CHECK" >> $SRS_AUTO_HEADERS_H
  462 +fi
@@ -138,8 +138,6 @@ END @@ -138,8 +138,6 @@ END
138 138
139 ##################################################################################### 139 #####################################################################################
140 # build tools or compiler args. 140 # build tools or compiler args.
141 -# the performance analysis, uncomments the following when use gperf to analysis the performance. see third-party/readme.txt  
142 -Performance="-pg"  
143 # enable gdb debug 141 # enable gdb debug
144 GDBDebug="-g -O0" 142 GDBDebug="-g -O0"
145 # the warning level. 143 # the warning level.
@@ -150,7 +148,7 @@ CppStd="-ansi" @@ -150,7 +148,7 @@ CppStd="-ansi"
150 LibraryCompile="-fPIC" 148 LibraryCompile="-fPIC"
151 # the cxx flag generated. 149 # the cxx flag generated.
152 CXXFLAGS="${CppStd} ${WarnLevel} ${GDBDebug} ${LibraryCompile}" 150 CXXFLAGS="${CppStd} ${WarnLevel} ${GDBDebug} ${LibraryCompile}"
153 -#CXXFLAGS="${CppStd} ${WarnLevel} ${GDBDebug} ${Performance}" 151 +if [ $SRS_GPERF = YES ]; then CXXFLAGS="${CXXFLAGS} -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free"; fi
154 cat << END > ${SRS_OBJS}/${SRS_MAKEFILE} 152 cat << END > ${SRS_OBJS}/${SRS_MAKEFILE}
155 CC ?= gcc 153 CC ?= gcc
156 GCC ?= gcc 154 GCC ?= gcc
@@ -178,6 +176,9 @@ if [ $SRS_HTTP = YES ]; then LibHttpParserRoot="${SRS_OBJS}/hp"; LibHttpParserfi @@ -178,6 +176,9 @@ if [ $SRS_HTTP = YES ]; then LibHttpParserRoot="${SRS_OBJS}/hp"; LibHttpParserfi
178 # openssl-1.0.1f, for the RTMP complex handshake. 176 # openssl-1.0.1f, for the RTMP complex handshake.
179 LibSSLRoot="";LibSSLfile="" 177 LibSSLRoot="";LibSSLfile=""
180 if [ $SRS_SSL = YES ]; then LibSSLRoot="${SRS_OBJS}/openssl/include"; LibSSLfile="${SRS_OBJS}/openssl/lib/libssl.a ${SRS_OBJS}/openssl/lib/libcrypto.a"; fi 178 if [ $SRS_SSL = YES ]; then LibSSLRoot="${SRS_OBJS}/openssl/include"; LibSSLfile="${SRS_OBJS}/openssl/lib/libssl.a ${SRS_OBJS}/openssl/lib/libcrypto.a"; fi
  179 +# gperftools-2.1, for mem check and mem/cpu profile
  180 +LibGperfRoot=""; LibGperfFile=""
  181 +if [ $SRS_GPERF = YES ]; then LibGperfRoot="${SRS_OBJS}/gperf/include"; LibGperfFile="${SRS_OBJS}/gperf/lib/libtcmalloc_and_profiler.a"; fi
181 182
182 ##################################################################################### 183 #####################################################################################
183 # Modules, compile each module, then link to binary 184 # Modules, compile each module, then link to binary
@@ -229,7 +230,7 @@ LIBS_OBJS="${MODULE_OBJS[@]}" @@ -229,7 +230,7 @@ LIBS_OBJS="${MODULE_OBJS[@]}"
229 #Main Module 230 #Main Module
230 MODULE_ID="MAIN" 231 MODULE_ID="MAIN"
231 MODULE_DEPENDS=("CORE" "KERNEL" "RTMP" "APP") 232 MODULE_DEPENDS=("CORE" "KERNEL" "RTMP" "APP")
232 -ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS}) 233 +ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS} ${LibGperfRoot})
233 MODULE_FILES=("srs_main_server" "srs_main_bandcheck") 234 MODULE_FILES=("srs_main_server" "srs_main_bandcheck")
234 MAIN_INCS="src/main"; MODULE_DIR=${MAIN_INCS} . auto/modules.sh 235 MAIN_INCS="src/main"; MODULE_DIR=${MAIN_INCS} . auto/modules.sh
235 MAIN_OBJS="${MODULE_OBJS[@]}" 236 MAIN_OBJS="${MODULE_OBJS[@]}"
@@ -242,10 +243,11 @@ MAIN_OBJS="${MODULE_OBJS[@]}" @@ -242,10 +243,11 @@ MAIN_OBJS="${MODULE_OBJS[@]}"
242 MAIN_ENTRANCES=("srs_main_server" "srs_main_bandcheck") 243 MAIN_ENTRANCES=("srs_main_server" "srs_main_bandcheck")
243 # 244 #
244 # all depends libraries 245 # all depends libraries
245 -ModuleLibFiles=(${LibSTfile} ${LibHttpParserfile} ${LibSSLfile}) 246 +ModuleLibFiles=(${LibSTfile} ${LibHttpParserfile} ${LibSSLfile} ${LibGperfFile})
246 # all depends objects 247 # all depends objects
247 MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${RTMP_OBJS[@]} ${APP_OBJS[@]} ${MAIN_OBJS[@]}" 248 MODULE_OBJS="${CORE_OBJS[@]} ${KERNEL_OBJS[@]} ${RTMP_OBJS[@]} ${APP_OBJS[@]} ${MAIN_OBJS[@]}"
248 LINK_OPTIONS="-ldl" 249 LINK_OPTIONS="-ldl"
  250 +if [ $SRS_GPERF = YES ]; then LINK_OPTIONS="${LINK_OPTIONS} -lpthread"; fi
249 # 251 #
250 # srs: 252 # srs:
251 # srs(simple rtmp server) over st(state-threads) 253 # srs(simple rtmp server) over st(state-threads)
@@ -335,4 +337,8 @@ fi @@ -335,4 +337,8 @@ fi
335 if [ $SRS_HTTP = YES ]; then 337 if [ $SRS_HTTP = YES ]; then
336 echo -e "\" python ./research/api-server/server.py 8085 \" to start the api-server" 338 echo -e "\" python ./research/api-server/server.py 8085 \" to start the api-server"
337 fi 339 fi
338 -echo "\" ./objs/srs -c conf/srs.conf \" to start the srs live server" 340 +if [ $SRS_GPERF = YES ]; then
  341 + echo "\" env HEAPCHECK=normal ./objs/srs -c conf/srs.conf \" to start the srs live server"
  342 +else
  343 + echo "\" ./objs/srs -c conf/srs.conf \" to start the srs live server"
  344 +fi
@@ -7,4 +7,4 @@ cpu_profiler: cpu_profiler.cc Makefile @@ -7,4 +7,4 @@ cpu_profiler: cpu_profiler.cc Makefile
7 -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free \ 7 -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free \
8 -I../../../objs/gperf/include ../../../objs/gperf/lib/libtcmalloc_and_profiler.a -lpthread 8 -I../../../objs/gperf/include ../../../objs/gperf/lib/libtcmalloc_and_profiler.a -lpthread
9 clean: 9 clean:
10 - rm -f cpu_profiler ./srs.conf* 10 + rm -f cpu_profiler ./srs.prof*
@@ -26,11 +26,11 @@ config srs with gperf(to make gperftools): @@ -26,11 +26,11 @@ config srs with gperf(to make gperftools):
26 set the pprof path if not set: 26 set the pprof path if not set:
27 export PPROF_PATH=`pwd`/../../../objs/pprof 27 export PPROF_PATH=`pwd`/../../../objs/pprof
28 to do cpu profile: 28 to do cpu profile:
29 - make && rm -f ./srs.conf* && env CPUPROFILE=./srs.conf ./cpu_profiler  
30 - $PPROF_PATH --text cpu_profiler ./srs.conf* 29 + make && rm -f ./srs.prof* && env CPUPROFILE=./srs.prof ./cpu_profiler
  30 + $PPROF_PATH --text cpu_profiler ./srs.prof*
31 to do cpu profile by signal: 31 to do cpu profile by signal:
32 - make && rm -f ./srs.conf* && env CPUPROFILE=./srs.conf CPUPROFILESIGNAL=12 ./cpu_profiler  
33 - $PPROF_PATH --text cpu_profiler ./srs.conf* 32 + make && rm -f ./srs.prof* && env CPUPROFILE=./srs.prof CPUPROFILESIGNAL=12 ./cpu_profiler
  33 + $PPROF_PATH --text cpu_profiler ./srs.prof*
34 */ 34 */
35 #include <stdio.h> 35 #include <stdio.h>
36 #include <unistd.h> 36 #include <unistd.h>
@@ -233,6 +233,14 @@ int SrsServer::cycle() @@ -233,6 +233,14 @@ int SrsServer::cycle()
233 srs_update_system_time_ms(); 233 srs_update_system_time_ms();
234 234
235 if (signal_reload) { 235 if (signal_reload) {
  236 +// for gperf heap checker,
  237 +// @see: research/gperftools/heap-checker/heap_checker.cc
  238 +// if user interrupt the program, exit to check mem leak.
  239 +// but, if gperf, use reload to terminate the server,
  240 +// for the SIGINT will cause core-dump.
  241 +#ifdef SRS_GPERF
  242 + break;
  243 +#endif
236 signal_reload = false; 244 signal_reload = false;
237 srs_info("get signal reload, to reload the config."); 245 srs_info("get signal reload, to reload the config.");
238 246
@@ -37,6 +37,13 @@ SrsServer* _srs_server = new SrsServer(); @@ -37,6 +37,13 @@ SrsServer* _srs_server = new SrsServer();
37 #include <stdlib.h> 37 #include <stdlib.h>
38 #include <signal.h> 38 #include <signal.h>
39 39
  40 +#ifdef SRS_GPERF_HEAP_PROFILE
  41 + #include <gperftools/heap-profiler.h>
  42 +#endif
  43 +#ifdef SRS_GPERF_CPU_PROFILE
  44 + #include <gperftools/profiler.h>
  45 +#endif
  46 +
40 void handler(int signo) 47 void handler(int signo)
41 { 48 {
42 srs_trace("get a signal, signo=%d", signo); 49 srs_trace("get a signal, signo=%d", signo);
@@ -47,6 +54,17 @@ int main(int argc, char** argv) @@ -47,6 +54,17 @@ int main(int argc, char** argv)
47 { 54 {
48 int ret = ERROR_SUCCESS; 55 int ret = ERROR_SUCCESS;
49 56
  57 +#ifdef SRS_GPERF_HEAP_CHECK
  58 + // env HEAPCHECK=normal ./objs/srs -c srs.conf
  59 +#endif
  60 +
  61 +#ifdef SRS_GPERF_HEAP_PROFILE
  62 + HeapProfilerStart("gperf.srs");
  63 +#endif
  64 +#ifdef SRS_GPERF_CPU_PROFILE
  65 + ProfilerStart("gperf.srs.prof");
  66 +#endif
  67 +
50 signal(SIGNAL_RELOAD, handler); 68 signal(SIGNAL_RELOAD, handler);
51 69
52 if ((ret = _srs_config->parse_options(argc, argv)) != ERROR_SUCCESS) { 70 if ((ret = _srs_config->parse_options(argc, argv)) != ERROR_SUCCESS) {