security/nss/tests/memleak/memleak.sh

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

mercurial