PageRenderTime 49ms CodeModel.GetById 13ms app.highlight 28ms RepoModel.GetById 1ms app.codeStats 1ms

/security/nss/tests/memleak/memleak.sh

http://github.com/zpao/v8monkey
Shell | 934 lines | 690 code | 121 blank | 123 comment | 53 complexity | 5e41df2a217e9526ae5114dcfb094d39 MD5 | raw file
  1#!/bin/bash
  2#
  3# ***** BEGIN LICENSE BLOCK *****
  4# Version: MPL 1.1/GPL 2.0/LGPL 2.1
  5#
  6# The contents of this file are subject to the Mozilla Public License Version
  7# 1.1 (the "License"); you may not use this file except in compliance with
  8# the License. You may obtain a copy of the License at
  9# http://www.mozilla.org/MPL/
 10#
 11# Software distributed under the License is distributed on an "AS IS" basis,
 12# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 13# for the specific language governing rights and limitations under the
 14# License.
 15#
 16# The Original Code is the Network Security Services (NSS)
 17#
 18# The Initial Developer of the Original Code is
 19# Sun Microsystems, Inc.
 20# Portions created by the Initial Developer are Copyright (C) 2006-2009
 21# the Initial Developer. All Rights Reserved.
 22#
 23# Contributor(s):
 24#   Slavomir Katuscak <slavomir.katuscak@sun.com>, Sun Microsystems
 25#
 26# Alternatively, the contents of this file may be used under the terms of
 27# either the GNU General Public License Version 2 or later (the "GPL"), or
 28# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 29# in which case the provisions of the GPL or the LGPL are applicable instead
 30# of those above. If you wish to allow use of your version of this file only
 31# under the terms of either the GPL or the LGPL, and not to allow others to
 32# use your version of this file under the terms of the MPL, indicate your
 33# decision by deleting the provisions above and replace them with the notice
 34# and other provisions required by the GPL or the LGPL. If you do not delete
 35# the provisions above, a recipient may use your version of this file under
 36# the terms of any one of the MPL, the GPL or the LGPL.
 37#
 38# ***** END LICENSE BLOCK *****
 39
 40########################################################################
 41#
 42# mozilla/security/nss/tests/memleak/memleak.sh
 43#
 44# Script to test memory leaks in NSS
 45#
 46# needs to work on Solaris and Linux platforms, on others just print a message
 47# that OS is not supported
 48#
 49# special strings
 50# ---------------
 51#   FIXME ... known problems, search for this string
 52#   NOTE .... unexpected behavior
 53#
 54########################################################################
 55
 56############################# memleak_init #############################
 57# local shell function to initialize this script 
 58########################################################################
 59memleak_init()
 60{
 61	if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then
 62		cd ../common
 63		. ./init.sh
 64	fi
 65	
 66	if [ ! -r ${CERT_LOG_FILE} ]; then
 67		cd ${QADIR}/cert
 68		. ./cert.sh
 69	fi
 70
 71	SCRIPTNAME="memleak.sh"
 72	if [ -z "${CLEANUP}" ] ; then
 73		CLEANUP="${SCRIPTNAME}"
 74	fi
 75
 76	OLD_LIBRARY_PATH=${LD_LIBRARY_PATH}
 77	TMP_LIBDIR="${HOSTDIR}/tmp"
 78	TMP_STACKS="${HOSTDIR}/stacks"
 79	TMP_SORTED="${HOSTDIR}/sorted"
 80	TMP_COUNT="${HOSTDIR}/count"
 81	DBXOUT="${HOSTDIR}/dbxout"
 82	DBXERR="${HOSTDIR}/dbxerr"
 83	DBXCMD="${HOSTDIR}/dbxcmd"
 84	
 85	PORT=${PORT:-8443}
 86	
 87	MODE_LIST="NORMAL BYPASS FIPS"
 88	
 89	SERVER_DB="${HOSTDIR}/server_memleak"
 90	CLIENT_DB="${HOSTDIR}/client_memleak"
 91	cp -r ${HOSTDIR}/server ${SERVER_DB}
 92	cp -r ${HOSTDIR}/client ${CLIENT_DB}
 93	
 94	LOGDIR="${HOSTDIR}/memleak_logs"
 95	mkdir -p ${LOGDIR}
 96
 97	FOUNDLEAKS="${LOGDIR}/foundleaks"
 98	
 99	REQUEST_FILE="${QADIR}/memleak/sslreq.dat"
100	IGNORED_STACKS="${QADIR}/memleak/ignored"
101	
102	gline=`echo ${OBJDIR} | grep "_64_"`
103	if [ -n "${gline}" ] ; then
104		BIT_NAME="64"
105	else
106		BIT_NAME="32"
107	fi
108		
109	case "${OS_NAME}" in
110	"SunOS")
111		DBX=`which dbx`
112		AWK=nawk
113		
114		if [ $? -eq 0 ] ; then
115			echo "${SCRIPTNAME}: DBX found: ${DBX}"
116		else
117			echo "${SCRIPTNAME}: DBX not found, skipping memory leak checking."
118			exit 0
119		fi
120		
121		PROC_ARCH=`uname -p`
122				
123		if [ "${PROC_ARCH}" = "sparc" ] ; then
124			if [ "${BIT_NAME}" = "64" ] ; then
125				FREEBL_DEFAULT="libfreebl_64fpu_3"
126				FREEBL_LIST="${FREEBL_DEFAULT} libfreebl_64int_3"
127			else
128				FREEBL_DEFAULT="libfreebl_32fpu_3"
129				FREEBL_LIST="${FREEBL_DEFAULT} libfreebl_32int_3 libfreebl_32int64_3"
130			fi
131		else
132			if [ "${BIT_NAME}" = "64" ] ; then
133				echo "${SCRIPTNAME}: OS not supported for memory leak checking."
134				exit 0
135			fi
136			
137			FREEBL_DEFAULT="libfreebl_3"
138			FREEBL_LIST="${FREEBL_DEFAULT}"
139		fi
140		
141		RUN_COMMAND_DBG="run_command_dbx"
142		PARSE_LOGFILE="parse_logfile_dbx"
143		;;
144	"Linux")
145		VALGRIND=`which valgrind`
146		AWK=awk
147		
148		if [ $? -eq 0 ] ; then
149			echo "${SCRIPTNAME}: Valgrind found: ${VALGRIND}"
150		else
151			echo "${SCRIPTNAME}: Valgrind not found, skipping memory leak checking."
152			exit 0
153		fi
154
155		if [ "${BIT_NAME}" = "64" ] ; then
156			echo "${SCRIPTNAME}: OS not supported for memory leak checking."
157			exit 0
158		fi
159		
160		FREEBL_DEFAULT="libfreebl_3"
161		FREEBL_LIST="${FREEBL_DEFAULT}"
162				
163		RUN_COMMAND_DBG="run_command_valgrind"
164		PARSE_LOGFILE="parse_logfile_valgrind"
165		;;
166	*)
167		echo "${SCRIPTNAME}: OS not supported for memory leak checking."
168		exit 0
169		;;
170	esac
171
172	if [ "${BUILD_OPT}" = "1" ] ; then
173		OPT="OPT"
174	else 
175		OPT="DBG"
176	fi
177
178	NSS_DISABLE_UNLOAD="1"
179	export NSS_DISABLE_UNLOAD
180
181	SELFSERV_ATTR="-D -p ${PORT} -d ${SERVER_DB} -n ${HOSTADDR} -e ${HOSTADDR}-ec -w nss -c ABCDEF:C001:C002:C003:C004:C005:C006:C007:C008:C009:C00A:C00B:C00C:C00D:C00E:C00F:C010:C011:C012:C013:C014cdefgijklmnvyz -t 5"
182	TSTCLNT_ATTR="-p ${PORT} -h ${HOSTADDR} -c j -f -d ${CLIENT_DB} -w nss -o"
183	STRSCLNT_ATTR="-q -p ${PORT} -d ${CLIENT_DB} -w nss -c 1000 -n TestUser ${HOSTADDR}"
184
185	tbytes=0
186	tblocks=0
187	truns=0
188	
189	MEMLEAK_DBG=1
190	export MEMLEAK_DBG
191}
192
193########################### memleak_cleanup ############################
194# local shell function to clean up after this script 
195########################################################################
196memleak_cleanup()
197{
198	unset MEMLEAK_DBG
199	unset NSS_DISABLE_UNLOAD
200	
201	. ${QADIR}/common/cleanup.sh
202}
203
204############################ set_test_mode #############################
205# local shell function to set testing mode for server and for client
206########################################################################
207set_test_mode()
208{
209	if [ "${server_mode}" = "BYPASS" ] ; then
210		echo "${SCRIPTNAME}: BYPASS is ON"
211		SERVER_OPTION="-B -s"
212		CLIENT_OPTION=""
213	elif [ "${client_mode}" = "BYPASS" ] ; then
214		echo "${SCRIPTNAME}: BYPASS is ON"
215		SERVER_OPTION=""
216		CLIENT_OPTION="-B -s"
217	else
218		echo "${SCRIPTNAME}: BYPASS is OFF"
219		SERVER_OPTION=""
220		CLIENT_OPTION=""
221	fi
222	
223	if [ "${server_mode}" = "FIPS" ] ; then
224		${BINDIR}/modutil -dbdir ${SERVER_DB} -fips true -force
225		${BINDIR}/modutil -dbdir ${SERVER_DB} -list
226		${BINDIR}/modutil -dbdir ${CLIENT_DB} -fips false -force
227		${BINDIR}/modutil -dbdir ${CLIENT_DB} -list
228		
229		echo "${SCRIPTNAME}: FIPS is ON"
230		cipher_list="c d e i j k n v y z"
231	elif [ "${client_mode}" = "FIPS" ] ; then
232		
233		${BINDIR}/modutil -dbdir ${SERVER_DB} -fips false -force
234		${BINDIR}/modutil -dbdir ${SERVER_DB} -list
235		${BINDIR}/modutil -dbdir ${CLIENT_DB} -fips true -force
236		${BINDIR}/modutil -dbdir ${CLIENT_DB} -list
237		
238		echo "${SCRIPTNAME}: FIPS is ON"
239		cipher_list="c d e i j k n v y z"
240	else
241		${BINDIR}/modutil -dbdir ${SERVER_DB} -fips false -force
242		${BINDIR}/modutil -dbdir ${SERVER_DB} -list
243		${BINDIR}/modutil -dbdir ${CLIENT_DB} -fips false -force
244		${BINDIR}/modutil -dbdir ${CLIENT_DB} -list
245		
246		echo "${SCRIPTNAME}: FIPS is OFF"
247		cipher_list="A B C D E F :C001 :C002 :C003 :C004 :C005 :C006 :C007 :C008 :C009 :C00A :C010 :C011 :C012 :C013 :C014 c d e f g i j k l m n v y z"
248	fi
249}
250
251############################## set_freebl ##############################
252# local shell function to set freebl - sets temporary path for libraries
253########################################################################
254set_freebl()
255{
256	if [ "${freebl}" = "${FREEBL_DEFAULT}" ] ; then
257		LD_LIBRARY_PATH="${OLD_LIBRARY_PATH}"
258		export LD_LIBRARY_PATH
259	else
260		if [ -d "${TMP_LIBDIR}" ] ; then
261			rm -rf ${TMP_LIBDIR}
262		fi
263
264		mkdir ${TMP_LIBDIR}
265		[ $? -ne 0 ] && html_failed "Create temp directory" && return 1
266
267		cp ${DIST}/${OBJDIR}/lib/*.so ${DIST}/${OBJDIR}/lib/*.chk ${TMP_LIBDIR}
268		[ $? -ne 0 ] && html_failed "Copy libraries to temp directory" && return 1
269		
270		echo "${SCRIPTNAME}: Using ${freebl} instead of ${FREEBL_DEFAULT}"
271
272		mv ${TMP_LIBDIR}/${FREEBL_DEFAULT}.so ${TMP_LIBDIR}/${FREEBL_DEFAULT}.so.orig
273		[ $? -ne 0 ] && html_failed "Move ${FREEBL_DEFAULT}.so -> ${FREEBL_DEFAULT}.so.orig" && return 1
274
275		cp ${TMP_LIBDIR}/${freebl}.so ${TMP_LIBDIR}/${FREEBL_DEFAULT}.so
276		[ $? -ne 0 ] && html_failed "Copy ${freebl}.so -> ${FREEBL_DEFAULT}.so" && return 1
277
278		mv ${TMP_LIBDIR}/${FREEBL_DEFAULT}.chk ${TMP_LIBDIR}/${FREEBL_DEFAULT}.chk.orig
279		[ $? -ne 0 ] && html_failed "Move ${FREEBL_DEFAULT}.chk -> ${FREEBL_DEFAULT}.chk.orig" && return 1
280
281		cp ${TMP_LIBDIR}/${freebl}.chk ${TMP_LIBDIR}/${FREEBL_DEFAULT}.chk
282		[ $? -ne 0 ] && html_failed "Copy ${freebl}.chk to temp directory" && return 1
283
284		echo "ls -l ${TMP_LIBDIR}"
285		ls -l ${TMP_LIBDIR}
286
287		LD_LIBRARY_PATH="${TMP_LIBDIR}"
288		export LD_LIBRARY_PATH
289	fi
290
291	return 0
292}
293
294############################# clear_freebl #############################
295# local shell function to set default library path and clear temporary 
296# directory for libraries created by function set_freebl 
297########################################################################
298clear_freebl()
299{
300	LD_LIBRARY_PATH="${OLD_LIBRARY_PATH}"
301	export LD_LIBRARY_PATH
302
303	if [ -d "${TMP_LIBDIR}" ] ; then
304		rm -rf ${TMP_LIBDIR}
305	fi
306}
307
308############################ run_command_dbx ###########################
309# local shell function to run command under dbx tool
310########################################################################
311run_command_dbx()
312{
313	COMMAND=$1
314	shift
315	ATTR=$*
316	
317	COMMAND=`which ${COMMAND}`
318	
319	echo "dbxenv follow_fork_mode parent" > ${DBXCMD}
320	echo "dbxenv rtc_mel_at_exit verbose" >> ${DBXCMD}
321	echo "dbxenv rtc_biu_at_exit verbose" >> ${DBXCMD}
322	echo "check -memuse -match 16 -frames 16" >> ${DBXCMD}
323	echo "run ${ATTR}" >> ${DBXCMD}
324	
325	export NSS_DISABLE_ARENA_FREE_LIST=1
326	
327	echo "${SCRIPTNAME}: -------- Running ${COMMAND} under DBX:"
328	echo "${DBX} ${COMMAND}"
329	echo "${SCRIPTNAME}: -------- DBX commands:"
330	cat ${DBXCMD}
331	
332	( ${DBX} ${COMMAND} < ${DBXCMD} > ${DBXOUT} 2> ${DBXERR} )
333	grep -v Reading ${DBXOUT} 1>&2
334	cat ${DBXERR}
335	
336	unset NSS_DISABLE_ARENA_FREE_LIST
337	
338	grep "exit code is" ${DBXOUT}
339	grep "exit code is 0" ${DBXOUT} > /dev/null
340	return $?
341}
342
343######################### run_command_valgrind #########################
344# local shell function to run command under valgrind tool
345########################################################################
346run_command_valgrind()
347{
348	COMMAND=$1
349	shift
350	ATTR=$*
351	
352	export NSS_DISABLE_ARENA_FREE_LIST=1
353	
354	echo "${SCRIPTNAME}: -------- Running ${COMMAND} under Valgrind:"
355	echo "${VALGRIND} --tool=memcheck --leak-check=yes --show-reachable=yes --partial-loads-ok=yes --leak-resolution=high --num-callers=50 ${COMMAND} ${ATTR}"
356	echo "Running: ${COMMAND} ${ATTR}" 1>&2
357	${VALGRIND} --tool=memcheck --leak-check=yes --show-reachable=yes --partial-loads-ok=yes --leak-resolution=high --num-callers=50 ${COMMAND} ${ATTR} 1>&2
358	ret=$?
359	echo "==0=="
360	
361	unset NSS_DISABLE_ARENA_FREE_LIST
362	
363	return $ret
364}
365
366############################# run_selfserv #############################
367# local shell function to start selfserv
368########################################################################
369run_selfserv()
370{
371	echo "PATH=${PATH}"
372	echo "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}"
373	echo "${SCRIPTNAME}: -------- Running selfserv:"
374	echo "selfserv ${SELFSERV_ATTR}"
375	${BINDIR}/selfserv ${SELFSERV_ATTR}
376	ret=$?
377	if [ $ret -ne 0 ]; then
378		html_failed "${LOGNAME}: Selfserv"
379		echo "${SCRIPTNAME} ${LOGNAME}: " \
380			"Selfserv produced a returncode of ${ret} - FAILED"
381	fi
382}
383
384########################### run_selfserv_dbg ###########################
385# local shell function to start selfserv under debug tool
386########################################################################
387run_selfserv_dbg()
388{
389	echo "PATH=${PATH}"
390	echo "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}"
391	${RUN_COMMAND_DBG} ${BINDIR}/selfserv ${SERVER_OPTION} ${SELFSERV_ATTR}
392	ret=$?
393	if [ $ret -ne 0 ]; then
394		html_failed "${LOGNAME}: Selfserv"
395		echo "${SCRIPTNAME} ${LOGNAME}: " \
396			"Selfserv produced a returncode of ${ret} - FAILED"
397	fi
398}
399
400############################# run_strsclnt #############################
401# local shell function to run strsclnt for all ciphers and send stop
402# command to selfserv over tstclnt
403########################################################################
404run_strsclnt()
405{
406	for cipher in ${cipher_list}; do
407		ATTR="${STRSCLNT_ATTR} -C ${cipher}"
408		echo "${SCRIPTNAME}: -------- Trying cipher ${cipher}:"
409		echo "strsclnt ${ATTR}"
410		${BINDIR}/strsclnt ${ATTR}
411		ret=$?
412		if [ $ret -ne 0 ]; then
413			html_failed "${LOGNAME}: Strsclnt with cipher ${cipher}"
414			echo "${SCRIPTNAME} ${LOGNAME}: " \
415				"Strsclnt produced a returncode of ${ret} - FAILED"
416		fi
417	done
418	
419	echo "${SCRIPTNAME}: -------- Stopping server:"
420	echo "tstclnt ${TSTCLNT_ATTR} < ${REQUEST_FILE}"
421	${BINDIR}/tstclnt ${TSTCLNT_ATTR} < ${REQUEST_FILE}
422	ret=$?
423	if [ $ret -ne 0 ]; then
424		html_failed "${LOGNAME}: Tstclnt"
425		echo "${SCRIPTNAME} ${LOGNAME}: " \
426			"Tstclnt produced a returncode of ${ret} - FAILED"
427	fi
428	
429	sleep 20
430	kill $(jobs -p) 2> /dev/null
431}
432
433########################### run_strsclnt_dbg ###########################
434# local shell function to run strsclnt under debug tool for all ciphers 
435# and send stop command to selfserv over tstclnt
436########################################################################
437run_strsclnt_dbg()
438{
439	for cipher in ${cipher_list}; do
440		ATTR="${STRSCLNT_ATTR} -C ${cipher}"
441		${RUN_COMMAND_DBG} ${BINDIR}/strsclnt ${CLIENT_OPTION} ${ATTR}
442		ret=$?
443		if [ $ret -ne 0 ]; then
444			html_failed "${LOGNAME}: Strsclnt with cipher ${cipher}"
445			echo "${SCRIPTNAME} ${LOGNAME}: " \
446				"Strsclnt produced a returncode of ${ret} - FAILED"
447		fi
448	done
449	
450	echo "${SCRIPTNAME}: -------- Stopping server:"
451	echo "tstclnt ${TSTCLNT_ATTR} < ${REQUEST_FILE}"
452	${BINDIR}/tstclnt ${TSTCLNT_ATTR} < ${REQUEST_FILE}
453	ret=$?
454	if [ $ret -ne 0 ]; then
455		html_failed "${LOGNAME}: Tstclnt"
456		echo "${SCRIPTNAME} ${LOGNAME}: " \
457			"Tstclnt produced a returncode of ${ret} - FAILED"
458	fi
459	
460	kill $(jobs -p) 2> /dev/null
461}
462
463stat_clear()
464{
465	stat_minbytes=9999999
466	stat_maxbytes=0
467	stat_minblocks=9999999
468	stat_maxblocks=0
469	stat_bytes=0
470	stat_blocks=0
471	stat_runs=0
472}
473
474stat_add()
475{
476	read hash lbytes bytes_str lblocks blocks_str in_str lruns runs_str \
477		minbytes minbytes_str maxbytes maxbytes_str minblocks \
478		minblocks_str maxblocks maxblocks_str rest < ${TMP_COUNT} 
479	rm ${TMP_COUNT}
480	
481	tbytes=`expr ${tbytes} + ${lbytes}`
482	tblocks=`expr ${tblocks} + ${lblocks}`
483	truns=`expr ${truns} + ${lruns}`
484	
485	if [ ${stat_minbytes} -gt ${minbytes} ]; then
486		stat_minbytes=${minbytes}
487	fi
488			
489	if [ ${stat_maxbytes} -lt ${maxbytes} ]; then
490		stat_maxbytes=${maxbytes}
491	fi
492			
493	if [ ${stat_minblocks} -gt ${minblocks} ]; then
494		stat_minblocks=${minblocks}
495	fi
496			
497	if [ ${stat_maxblocks} -lt ${maxblocks} ]; then
498		stat_maxblocks=${maxblocks}
499	fi
500			
501	stat_bytes=`expr ${stat_bytes} + ${lbytes}`
502	stat_blocks=`expr ${stat_blocks} + ${lblocks}`
503	stat_runs=`expr ${stat_runs} + ${lruns}`
504}
505
506stat_print()
507{
508	if [ ${stat_runs} -gt 0 ]; then
509		stat_avgbytes=`expr "${stat_bytes}" / "${stat_runs}"`
510		stat_avgblocks=`expr "${stat_blocks}" / "${stat_runs}"`
511		
512		echo
513		echo "$1 statistics:"
514		echo "Leaked bytes: ${stat_minbytes} min, ${stat_avgbytes} avg, ${stat_maxbytes} max"
515		echo "Leaked blocks: ${stat_minblocks} min, ${stat_avgblocks} avg, ${stat_maxblocks} max"
516		echo "Total runs: ${stat_runs}"
517		echo
518	fi
519}
520
521########################## run_ciphers_server ##########################
522# local shell function to test server part of code (selfserv)
523########################################################################
524run_ciphers_server()
525{
526	html_head "Memory leak checking - server"
527	
528	stat_clear
529	
530	client_mode="NORMAL"	
531	for server_mode in ${MODE_LIST}; do
532		set_test_mode
533		
534		for freebl in ${FREEBL_LIST}; do
535			set_freebl || continue
536			
537			LOGNAME=server-${BIT_NAME}-${freebl}-${server_mode}
538			LOGFILE=${LOGDIR}/${LOGNAME}.log
539			echo "Running ${LOGNAME}"
540			
541			(
542			    run_selfserv_dbg 2>> ${LOGFILE} &
543			    sleep 5
544			    run_strsclnt
545			)
546			
547			sleep 20
548			clear_freebl
549			
550			log_parse
551			ret=$?
552			
553			html_msg ${ret} 0 "${LOGNAME}" "produced a returncode of $ret, expected is 0"
554		done
555	done
556	
557	stat_print "Selfserv"
558	
559	html "</TABLE><BR>"
560}
561
562########################## run_ciphers_client ##########################
563# local shell function to test client part of code (strsclnt)
564########################################################################
565run_ciphers_client()
566{
567	html_head "Memory leak checking - client"
568	
569	stat_clear
570	
571	server_mode="NORMAL"
572	for client_mode in ${MODE_LIST}; do
573		set_test_mode
574		
575		for freebl in ${FREEBL_LIST}; do
576			set_freebl || continue
577			
578			LOGNAME=client-${BIT_NAME}-${freebl}-${client_mode}
579			LOGFILE=${LOGDIR}/${LOGNAME}.log
580			echo "Running ${LOGNAME}"
581			
582			(
583			    run_selfserv &
584			    sleep 5
585			    run_strsclnt_dbg 2>> ${LOGFILE}
586			)
587			
588			sleep 20
589			clear_freebl
590			
591			log_parse
592			ret=$?
593			html_msg ${ret} 0 "${LOGNAME}" "produced a returncode of $ret, expected is 0"
594		done
595	done
596	
597	stat_print "Strsclnt"
598	
599	html "</TABLE><BR>"
600}
601
602########################## parse_logfile_dbx ###########################
603# local shell function to parse and process logs from dbx
604########################################################################
605parse_logfile_dbx()
606{
607	${AWK} '
608	BEGIN {
609		in_mel = 0
610		mel_line = 0
611		bytes = 0
612		lbytes = 0
613		minbytes = 9999999
614		maxbytes = 0
615		blocks = 0
616		lblocks = 0
617		minblocks = 9999999
618		maxblocks = 0
619		runs = 0
620		stack_string = ""
621		bin_name = ""
622	}
623	/Memory Leak \(mel\):/ ||
624	/Possible memory leak -- address in block \(aib\):/ ||
625	/Block in use \(biu\):/ {
626		in_mel = 1
627		stack_string = ""
628		next
629	}
630	in_mel == 1 && /^$/ {
631		print bin_name stack_string
632		in_mel = 0
633		mel_line = 0
634		next
635	}
636	in_mel == 1 {
637		mel_line += 1
638	}
639	/Found leaked block of size/ {
640		bytes += $6
641		blocks += 1
642		next
643	}
644	/Found .* leaked blocks/ {
645		bytes += $8
646		blocks += $2
647		next
648	}
649	/Found block of size/ {
650		bytes += $5
651		blocks += 1
652		next
653	}
654	/Found .* blocks totaling/ {
655		bytes += $5
656		blocks += $2
657		next
658	}
659	mel_line > 2 {
660		gsub(/\(\)/, "")
661		new_line = $2
662		stack_string = "/" new_line stack_string
663		next
664	}
665	/^Running: / {
666		bin_name = $2
667		next
668	}
669	/execution completed/ {
670		runs += 1
671		lbytes += bytes
672		minbytes = (minbytes < bytes) ? minbytes : bytes
673		maxbytes = (maxbytes > bytes) ? maxbytes : bytes
674		bytes = 0
675		lblocks += blocks
676		minblocks = (minblocks < blocks) ? minblocks : blocks
677		maxblocks = (maxblocks > blocks) ? maxblocks : blocks
678		blocks = 0
679		next
680	}
681	END {
682		print "# " lbytes " bytes " lblocks " blocks in " runs " runs " \
683		minbytes " minbytes " maxbytes " maxbytes " minblocks " minblocks " \
684		maxblocks " maxblocks " > "/dev/stderr"
685	}' 2> ${TMP_COUNT}
686	
687	stat_add
688}
689
690######################## parse_logfile_valgrind ########################
691# local shell function to parse and process logs from valgrind
692########################################################################
693parse_logfile_valgrind()
694{
695	${AWK} '
696	BEGIN {
697		in_mel = 0
698		in_sum = 0
699		bytes = 0
700		lbytes = 0
701		minbytes = 9999999
702		maxbytes = 0
703		blocks = 0
704		lblocks = 0
705		minblocks = 9999999
706		maxblocks = 0
707		runs = 0
708		stack_string = ""
709		bin_name = "" 
710	}
711	!/==[0-9]*==/ { 
712		if ( $1 == "Running:" ) 
713			bin_name = $2
714			bin_nf = split(bin_name, bin_fields, "/")
715			bin_name = bin_fields[bin_nf]
716		next
717	}
718	/blocks are/ {
719		in_mel = 1
720		stack_string = ""
721		next
722	}
723	/LEAK SUMMARY/ {
724		in_sum = 1
725		next
726	}
727	/^==[0-9]*== *$/ { 
728		if (in_mel)
729			print bin_name stack_string
730		if (in_sum) {
731			runs += 1
732			lbytes += bytes
733			minbytes = (minbytes < bytes) ? minbytes : bytes
734			maxbytes = (maxbytes > bytes) ? maxbytes : bytes
735			bytes = 0
736			lblocks += blocks
737			minblocks = (minblocks < blocks) ? minblocks : blocks
738			maxblocks = (maxblocks > blocks) ? maxblocks : blocks
739			blocks = 0
740		}
741		in_sum = 0
742		in_mel = 0
743		next
744	}
745	in_mel == 1 {	
746		new_line = $4
747		if ( new_line == "(within")
748			new_line = "*"
749		stack_string = "/" new_line stack_string
750	}
751	in_sum == 1 {
752		for (i = 2; i <= NF; i++) {
753			if ($i == "bytes") {
754				str = $(i - 1)
755				gsub(",", "", str)
756				bytes += str
757			}
758			if ($i == "blocks.") {
759				str = $(i - 1)
760				gsub(",", "", str)
761				blocks += str
762			}
763		}
764	}
765	END {
766		print "# " lbytes " bytes " lblocks " blocks in " runs " runs " \
767		minbytes " minbytes " maxbytes " maxbytes " minblocks " minblocks " \
768		maxblocks " maxblocks " > "/dev/stderr"
769	}' 2> ${TMP_COUNT}
770	
771	stat_add
772}
773
774############################# check_ignored ############################
775# local shell function to check all stacks if they are not ignored
776########################################################################
777check_ignored()
778{
779	${AWK} -F/ '
780	BEGIN {
781		ignore = "'${IGNORED_STACKS}'"
782		# read in the ignore file
783		BUGNUM = ""
784		count = 0
785		new = 0
786		while ((getline line < ignore) > 0)  {
787			if (line ~ "^#[0-9]+") {
788				BUGNUM = line
789			} else if (line ~ "^#") {
790				continue
791			} else if (line == "") {
792				continue
793			} else {
794				bugnum_array[count] = BUGNUM
795				# Create a regular expression for the ignored stack:
796				# replace * with % so we can later replace them with regular expressions
797				# without messing up everything (the regular expressions contain *)
798				gsub("\\*", "%", line)
799				# replace %% with .*
800				gsub("%%", ".*", line)
801				# replace % with [^/]*
802				gsub("%", "[^/]*", line)
803				# add ^ at the beginning
804				# add $ at the end
805				line_array[count] = "^" line "$"
806				count++
807			}
808		}
809	}
810	{
811		match_found = 0
812		# Look for matching ignored stack
813		for (i = 0; i < count; i++) {
814			if ($0 ~ line_array[i]) {
815				# found a match
816				match_found = 1
817				bug_found = bugnum_array[i]
818				break
819			}
820		}
821		# Process result
822		if (match_found == 1 ) {
823				if (bug_found != "") {
824					print "IGNORED STACK (" bug_found "): " $0
825				} else {
826					print "IGNORED STACK: " $0
827				}
828		} else {
829				print "NEW STACK: " $0
830				new = 1
831		}
832	}
833	END {
834		exit new
835	}'
836	ret=$?
837	return $ret
838}
839
840############################### parse_log ##############################
841# local shell function to parse log file
842########################################################################
843log_parse()
844{
845	${PARSE_LOGFILE} < ${LOGFILE} > ${TMP_STACKS}
846	echo "${SCRIPTNAME}: Processing log ${LOGNAME}:" > ${TMP_SORTED}
847	cat ${TMP_STACKS} | sort -u | check_ignored >> ${TMP_SORTED}
848	ret=$?
849	echo >> ${TMP_SORTED}
850	
851	cat ${TMP_SORTED} | tee -a ${FOUNDLEAKS}
852	rm ${TMP_STACKS} ${TMP_SORTED}
853	
854	return ${ret}
855}
856
857############################## cnt_total ###############################
858# local shell function to count total leaked bytes
859########################################################################
860cnt_total()
861{
862	echo ""
863	echo "TinderboxPrint:${OPT} Lk bytes: ${tbytes}"
864	echo "TinderboxPrint:${OPT} Lk blocks: ${tblocks}"
865	echo "TinderboxPrint:${OPT} # of runs: ${truns}"
866	echo ""
867}
868
869############################### run_ocsp ###############################
870# local shell function to run ocsp tests
871########################################################################
872run_ocsp()
873{
874	stat_clear
875	
876	cd ${QADIR}/iopr
877	. ./ocsp_iopr.sh
878	ocsp_iopr_run
879	
880	stat_print "Ocspclnt"
881}
882
883############################## run_chains ##############################
884# local shell function to run PKIX certificate chains tests
885########################################################################
886run_chains()
887{
888    stat_clear
889
890    LOGNAME="chains"
891    LOGFILE=${LOGDIR}/chains.log
892
893    . ${QADIR}/chains/chains.sh
894
895    stat_print "Chains"
896}
897
898############################## run_chains ##############################
899# local shell function to run memory leak tests
900#
901# NSS_MEMLEAK_TESTS - list of tests to run, if not defined before,
902# then is redefined to default list 
903########################################################################
904memleak_run_tests()
905{
906    nss_memleak_tests="ssl_server ssl_client chains ocsp"
907    NSS_MEMLEAK_TESTS="${NSS_MEMLEAK_TESTS:-$nss_memleak_tests}"
908
909    for MEMLEAK_TEST in ${NSS_MEMLEAK_TESTS}
910    do
911        case "${MEMLEAK_TEST}" in
912        "ssl_server")
913            run_ciphers_server
914            ;;
915        "ssl_client")
916            run_ciphers_client
917            ;;
918        "chains")
919            run_chains
920            ;;
921        "ocsp")
922            run_ocsp
923            ;;
924        esac
925    done
926}
927
928################################# main #################################
929
930memleak_init
931memleak_run_tests
932cnt_total
933memleak_cleanup
934