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######################################################################## 26memleak_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 :C001:C002:C003:C004:C005:C006:C007:C008:C009:C00A:C00B:C00C:C00D:C00E:C00F:C010:C011:C012:C013:C014cdefgijklmnvyz -t 5 -V ssl3:tls1.2" 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######################################################################## 158memleak_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######################################################################## 169set_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 # ciphers l and m removed, see bug 1136095 210 cipher_list=":C001 :C002 :C003 :C004 :C005 :C006 :C007 :C008 :C009 :C00A :C010 :C011 :C012 :C013 :C014 c d e f g i j k n v y z" 211 fi 212} 213 214############################## set_freebl ############################## 215# local shell function to set freebl - sets temporary path for libraries 216######################################################################## 217set_freebl() 218{ 219 if [ "${freebl}" = "${FREEBL_DEFAULT}" ] ; then 220 LD_LIBRARY_PATH="${OLD_LIBRARY_PATH}" 221 export LD_LIBRARY_PATH 222 else 223 if [ -d "${TMP_LIBDIR}" ] ; then 224 rm -rf ${TMP_LIBDIR} 225 fi 226 227 mkdir ${TMP_LIBDIR} 228 [ $? -ne 0 ] && html_failed "Create temp directory" && return 1 229 230 cp ${DIST}/${OBJDIR}/lib/*.so ${DIST}/${OBJDIR}/lib/*.chk ${TMP_LIBDIR} 231 [ $? -ne 0 ] && html_failed "Copy libraries to temp directory" && return 1 232 233 echo "${SCRIPTNAME}: Using ${freebl} instead of ${FREEBL_DEFAULT}" 234 235 mv ${TMP_LIBDIR}/${FREEBL_DEFAULT}.so ${TMP_LIBDIR}/${FREEBL_DEFAULT}.so.orig 236 [ $? -ne 0 ] && html_failed "Move ${FREEBL_DEFAULT}.so -> ${FREEBL_DEFAULT}.so.orig" && return 1 237 238 cp ${TMP_LIBDIR}/${freebl}.so ${TMP_LIBDIR}/${FREEBL_DEFAULT}.so 239 [ $? -ne 0 ] && html_failed "Copy ${freebl}.so -> ${FREEBL_DEFAULT}.so" && return 1 240 241 mv ${TMP_LIBDIR}/${FREEBL_DEFAULT}.chk ${TMP_LIBDIR}/${FREEBL_DEFAULT}.chk.orig 242 [ $? -ne 0 ] && html_failed "Move ${FREEBL_DEFAULT}.chk -> ${FREEBL_DEFAULT}.chk.orig" && return 1 243 244 cp ${TMP_LIBDIR}/${freebl}.chk ${TMP_LIBDIR}/${FREEBL_DEFAULT}.chk 245 [ $? -ne 0 ] && html_failed "Copy ${freebl}.chk to temp directory" && return 1 246 247 echo "ls -l ${TMP_LIBDIR}" 248 ls -l ${TMP_LIBDIR} 249 250 LD_LIBRARY_PATH="${TMP_LIBDIR}" 251 export LD_LIBRARY_PATH 252 fi 253 254 return 0 255} 256 257############################# clear_freebl ############################# 258# local shell function to set default library path and clear temporary 259# directory for libraries created by function set_freebl 260######################################################################## 261clear_freebl() 262{ 263 LD_LIBRARY_PATH="${OLD_LIBRARY_PATH}" 264 export LD_LIBRARY_PATH 265 266 if [ -d "${TMP_LIBDIR}" ] ; then 267 rm -rf ${TMP_LIBDIR} 268 fi 269} 270 271############################ run_command_dbx ########################### 272# local shell function to run command under dbx tool 273######################################################################## 274run_command_dbx() 275{ 276 COMMAND=$1 277 shift 278 ATTR=$* 279 280 COMMAND=`which ${COMMAND}` 281 282 echo "dbxenv follow_fork_mode parent" > ${DBXCMD} 283 echo "dbxenv rtc_mel_at_exit verbose" >> ${DBXCMD} 284 echo "dbxenv rtc_biu_at_exit verbose" >> ${DBXCMD} 285 echo "check -memuse -match 16 -frames 16" >> ${DBXCMD} 286 echo "run ${ATTR}" >> ${DBXCMD} 287 288 export NSS_DISABLE_ARENA_FREE_LIST=1 289 290 echo "${SCRIPTNAME}: -------- Running ${COMMAND} under DBX:" 291 echo "${DBX} ${COMMAND}" 292 echo "${SCRIPTNAME}: -------- DBX commands:" 293 cat ${DBXCMD} 294 295 ( ${DBX} ${COMMAND} < ${DBXCMD} > ${DBXOUT} 2> ${DBXERR} ) 296 grep -v Reading ${DBXOUT} 1>&2 297 cat ${DBXERR} 298 299 unset NSS_DISABLE_ARENA_FREE_LIST 300 301 grep "exit code is" ${DBXOUT} 302 grep "exit code is 0" ${DBXOUT} > /dev/null 303 return $? 304} 305 306######################### run_command_valgrind ######################### 307# local shell function to run command under valgrind tool 308######################################################################## 309run_command_valgrind() 310{ 311 COMMAND=$1 312 shift 313 ATTR=$* 314 315 export NSS_DISABLE_ARENA_FREE_LIST=1 316 317 echo "${SCRIPTNAME}: -------- Running ${COMMAND} under Valgrind:" 318 echo "${VALGRIND} --tool=memcheck --leak-check=yes --show-reachable=yes --partial-loads-ok=yes --leak-resolution=high --num-callers=50 ${COMMAND} ${ATTR}" 319 echo "Running: ${COMMAND} ${ATTR}" 1>&2 320 ${VALGRIND} --tool=memcheck --leak-check=yes --show-reachable=yes --partial-loads-ok=yes --leak-resolution=high --num-callers=50 ${COMMAND} ${ATTR} 1>&2 321 ret=$? 322 echo "==0==" 323 324 unset NSS_DISABLE_ARENA_FREE_LIST 325 326 return $ret 327} 328 329############################# run_selfserv ############################# 330# local shell function to start selfserv 331######################################################################## 332run_selfserv() 333{ 334 echo "PATH=${PATH}" 335 echo "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" 336 echo "${SCRIPTNAME}: -------- Running selfserv:" 337 echo "selfserv ${SELFSERV_ATTR}" 338 ${BINDIR}/selfserv ${SELFSERV_ATTR} 339 ret=$? 340 if [ $ret -ne 0 ]; then 341 html_failed "${LOGNAME}: Selfserv" 342 echo "${SCRIPTNAME} ${LOGNAME}: " \ 343 "Selfserv produced a returncode of ${ret} - FAILED" 344 fi 345} 346 347########################### run_selfserv_dbg ########################### 348# local shell function to start selfserv under debug tool 349######################################################################## 350run_selfserv_dbg() 351{ 352 echo "PATH=${PATH}" 353 echo "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" 354 ${RUN_COMMAND_DBG} ${BINDIR}/selfserv ${SERVER_OPTION} ${SELFSERV_ATTR} 355 ret=$? 356 if [ $ret -ne 0 ]; then 357 html_failed "${LOGNAME}: Selfserv" 358 echo "${SCRIPTNAME} ${LOGNAME}: " \ 359 "Selfserv produced a returncode of ${ret} - FAILED" 360 fi 361} 362 363############################# run_strsclnt ############################# 364# local shell function to run strsclnt for all ciphers and send stop 365# command to selfserv over tstclnt 366######################################################################## 367run_strsclnt() 368{ 369 for cipher in ${cipher_list}; do 370 VMIN="ssl3" 371 VMAX="tls1.2" 372 case "${cipher}" in 373 f|g) 374 # TLS 1.1 disallows export cipher suites. 375 VMAX="tls1.0" 376 ;; 377 esac 378 ATTR="${STRSCLNT_ATTR} -C ${cipher} -V ${VMIN}:${VMAX}" 379 echo "${SCRIPTNAME}: -------- Trying cipher ${cipher}:" 380 echo "strsclnt ${ATTR}" 381 ${BINDIR}/strsclnt ${ATTR} 382 ret=$? 383 if [ $ret -ne 0 ]; then 384 html_failed "${LOGNAME}: Strsclnt with cipher ${cipher}" 385 echo "${SCRIPTNAME} ${LOGNAME}: " \ 386 "Strsclnt produced a returncode of ${ret} - FAILED" 387 fi 388 done 389 390 ATTR="${TSTCLNT_ATTR} -V ssl3:tls1.2" 391 echo "${SCRIPTNAME}: -------- Stopping server:" 392 echo "tstclnt ${ATTR} < ${REQUEST_FILE}" 393 ${BINDIR}/tstclnt ${ATTR} < ${REQUEST_FILE} 394 ret=$? 395 if [ $ret -ne 0 ]; then 396 html_failed "${LOGNAME}: Tstclnt" 397 echo "${SCRIPTNAME} ${LOGNAME}: " \ 398 "Tstclnt produced a returncode of ${ret} - FAILED" 399 fi 400 401 sleep 20 402 kill $(jobs -p) 2> /dev/null 403} 404 405########################### run_strsclnt_dbg ########################### 406# local shell function to run strsclnt under debug tool for all ciphers 407# and send stop command to selfserv over tstclnt 408######################################################################## 409run_strsclnt_dbg() 410{ 411 for cipher in ${cipher_list}; do 412 VMIN="ssl3" 413 VMAX="tls1.2" 414 case "${cipher}" in 415 f|g) 416 # TLS 1.1 disallows export cipher suites. 417 VMAX="tls1.0" 418 ;; 419 esac 420 ATTR="${STRSCLNT_ATTR} -C ${cipher} -V ${VMIN}:${VMAX}" 421 ${RUN_COMMAND_DBG} ${BINDIR}/strsclnt ${CLIENT_OPTION} ${ATTR} 422 ret=$? 423 if [ $ret -ne 0 ]; then 424 html_failed "${LOGNAME}: Strsclnt with cipher ${cipher}" 425 echo "${SCRIPTNAME} ${LOGNAME}: " \ 426 "Strsclnt produced a returncode of ${ret} - FAILED" 427 fi 428 done 429 430 ATTR="${TSTCLNT_ATTR} -V ssl3:tls1.2" 431 echo "${SCRIPTNAME}: -------- Stopping server:" 432 echo "tstclnt ${ATTR} < ${REQUEST_FILE}" 433 ${BINDIR}/tstclnt ${ATTR} < ${REQUEST_FILE} 434 ret=$? 435 if [ $ret -ne 0 ]; then 436 html_failed "${LOGNAME}: Tstclnt" 437 echo "${SCRIPTNAME} ${LOGNAME}: " \ 438 "Tstclnt produced a returncode of ${ret} - FAILED" 439 fi 440 441 kill $(jobs -p) 2> /dev/null 442} 443 444stat_clear() 445{ 446 stat_minbytes=9999999 447 stat_maxbytes=0 448 stat_minblocks=9999999 449 stat_maxblocks=0 450 stat_bytes=0 451 stat_blocks=0 452 stat_runs=0 453} 454 455stat_add() 456{ 457 read hash lbytes bytes_str lblocks blocks_str in_str lruns runs_str \ 458 minbytes minbytes_str maxbytes maxbytes_str minblocks \ 459 minblocks_str maxblocks maxblocks_str rest < ${TMP_COUNT} 460 rm ${TMP_COUNT} 461 462 tbytes=`expr ${tbytes} + ${lbytes}` 463 tblocks=`expr ${tblocks} + ${lblocks}` 464 truns=`expr ${truns} + ${lruns}` 465 466 if [ ${stat_minbytes} -gt ${minbytes} ]; then 467 stat_minbytes=${minbytes} 468 fi 469 470 if [ ${stat_maxbytes} -lt ${maxbytes} ]; then 471 stat_maxbytes=${maxbytes} 472 fi 473 474 if [ ${stat_minblocks} -gt ${minblocks} ]; then 475 stat_minblocks=${minblocks} 476 fi 477 478 if [ ${stat_maxblocks} -lt ${maxblocks} ]; then 479 stat_maxblocks=${maxblocks} 480 fi 481 482 stat_bytes=`expr ${stat_bytes} + ${lbytes}` 483 stat_blocks=`expr ${stat_blocks} + ${lblocks}` 484 stat_runs=`expr ${stat_runs} + ${lruns}` 485} 486 487stat_print() 488{ 489 if [ ${stat_runs} -gt 0 ]; then 490 stat_avgbytes=`expr "${stat_bytes}" / "${stat_runs}"` 491 stat_avgblocks=`expr "${stat_blocks}" / "${stat_runs}"` 492 493 echo 494 echo "$1 statistics:" 495 echo "Leaked bytes: ${stat_minbytes} min, ${stat_avgbytes} avg, ${stat_maxbytes} max" 496 echo "Leaked blocks: ${stat_minblocks} min, ${stat_avgblocks} avg, ${stat_maxblocks} max" 497 echo "Total runs: ${stat_runs}" 498 echo 499 fi 500} 501 502########################## run_ciphers_server ########################## 503# local shell function to test server part of code (selfserv) 504######################################################################## 505run_ciphers_server() 506{ 507 html_head "Memory leak checking - server" 508 509 stat_clear 510 511 client_mode="NORMAL" 512 for server_mode in ${MODE_LIST}; do 513 set_test_mode 514 515 for freebl in ${FREEBL_LIST}; do 516 set_freebl || continue 517 518 LOGNAME=server-${BIT_NAME}-${freebl}-${server_mode} 519 LOGFILE=${LOGDIR}/${LOGNAME}.log 520 echo "Running ${LOGNAME}" 521 522 ( 523 run_selfserv_dbg 2>> ${LOGFILE} & 524 sleep 5 525 run_strsclnt 526 ) 527 528 sleep 20 529 clear_freebl 530 531 log_parse 532 ret=$? 533 534 html_msg ${ret} 0 "${LOGNAME}" "produced a returncode of $ret, expected is 0" 535 done 536 done 537 538 stat_print "Selfserv" 539 540 html "</TABLE><BR>" 541} 542 543########################## run_ciphers_client ########################## 544# local shell function to test client part of code (strsclnt) 545######################################################################## 546run_ciphers_client() 547{ 548 html_head "Memory leak checking - client" 549 550 stat_clear 551 552 server_mode="NORMAL" 553 for client_mode in ${MODE_LIST}; do 554 set_test_mode 555 556 for freebl in ${FREEBL_LIST}; do 557 set_freebl || continue 558 559 LOGNAME=client-${BIT_NAME}-${freebl}-${client_mode} 560 LOGFILE=${LOGDIR}/${LOGNAME}.log 561 echo "Running ${LOGNAME}" 562 563 ( 564 run_selfserv & 565 sleep 5 566 run_strsclnt_dbg 2>> ${LOGFILE} 567 ) 568 569 sleep 20 570 clear_freebl 571 572 log_parse 573 ret=$? 574 html_msg ${ret} 0 "${LOGNAME}" "produced a returncode of $ret, expected is 0" 575 done 576 done 577 578 stat_print "Strsclnt" 579 580 html "</TABLE><BR>" 581} 582 583########################## parse_logfile_dbx ########################### 584# local shell function to parse and process logs from dbx 585######################################################################## 586parse_logfile_dbx() 587{ 588 ${AWK} ' 589 BEGIN { 590 in_mel = 0 591 mel_line = 0 592 bytes = 0 593 lbytes = 0 594 minbytes = 9999999 595 maxbytes = 0 596 blocks = 0 597 lblocks = 0 598 minblocks = 9999999 599 maxblocks = 0 600 runs = 0 601 stack_string = "" 602 bin_name = "" 603 } 604 /Memory Leak \(mel\):/ || 605 /Possible memory leak -- address in block \(aib\):/ || 606 /Block in use \(biu\):/ { 607 in_mel = 1 608 stack_string = "" 609 next 610 } 611 in_mel == 1 && /^$/ { 612 print bin_name stack_string 613 in_mel = 0 614 mel_line = 0 615 next 616 } 617 in_mel == 1 { 618 mel_line += 1 619 } 620 /Found leaked block of size/ { 621 bytes += $6 622 blocks += 1 623 next 624 } 625 /Found .* leaked blocks/ { 626 bytes += $8 627 blocks += $2 628 next 629 } 630 /Found block of size/ { 631 bytes += $5 632 blocks += 1 633 next 634 } 635 /Found .* blocks totaling/ { 636 bytes += $5 637 blocks += $2 638 next 639 } 640 mel_line > 2 { 641 gsub(/\(\)/, "") 642 new_line = $2 643 stack_string = "/" new_line stack_string 644 next 645 } 646 /^Running: / { 647 bin_name = $2 648 next 649 } 650 /execution completed/ { 651 runs += 1 652 lbytes += bytes 653 minbytes = (minbytes < bytes) ? minbytes : bytes 654 maxbytes = (maxbytes > bytes) ? maxbytes : bytes 655 bytes = 0 656 lblocks += blocks 657 minblocks = (minblocks < blocks) ? minblocks : blocks 658 maxblocks = (maxblocks > blocks) ? maxblocks : blocks 659 blocks = 0 660 next 661 } 662 END { 663 print "# " lbytes " bytes " lblocks " blocks in " runs " runs " \ 664 minbytes " minbytes " maxbytes " maxbytes " minblocks " minblocks " \ 665 maxblocks " maxblocks " > "/dev/stderr" 666 }' 2> ${TMP_COUNT} 667 668 stat_add 669} 670 671######################## parse_logfile_valgrind ######################## 672# local shell function to parse and process logs from valgrind 673######################################################################## 674parse_logfile_valgrind() 675{ 676 ${AWK} ' 677 BEGIN { 678 in_mel = 0 679 in_sum = 0 680 bytes = 0 681 lbytes = 0 682 minbytes = 9999999 683 maxbytes = 0 684 blocks = 0 685 lblocks = 0 686 minblocks = 9999999 687 maxblocks = 0 688 runs = 0 689 stack_string = "" 690 bin_name = "" 691 } 692 !/==[0-9]*==/ { 693 if ( $1 == "Running:" ) 694 bin_name = $2 695 bin_nf = split(bin_name, bin_fields, "/") 696 bin_name = bin_fields[bin_nf] 697 next 698 } 699 /blocks are/ { 700 in_mel = 1 701 stack_string = "" 702 next 703 } 704 /LEAK SUMMARY/ { 705 in_sum = 1 706 next 707 } 708 /^==[0-9]*== *$/ { 709 if (in_mel) 710 print bin_name stack_string 711 if (in_sum) { 712 runs += 1 713 lbytes += bytes 714 minbytes = (minbytes < bytes) ? minbytes : bytes 715 maxbytes = (maxbytes > bytes) ? maxbytes : bytes 716 bytes = 0 717 lblocks += blocks 718 minblocks = (minblocks < blocks) ? minblocks : blocks 719 maxblocks = (maxblocks > blocks) ? maxblocks : blocks 720 blocks = 0 721 } 722 in_sum = 0 723 in_mel = 0 724 next 725 } 726 in_mel == 1 { 727 new_line = $4 728 if ( new_line == "(within") 729 new_line = "*" 730 stack_string = "/" new_line stack_string 731 } 732 in_sum == 1 { 733 for (i = 2; i <= NF; i++) { 734 if ($i == "bytes") { 735 str = $(i - 1) 736 gsub(",", "", str) 737 bytes += str 738 } 739 if ($i == "blocks.") { 740 str = $(i - 1) 741 gsub(",", "", str) 742 blocks += str 743 } 744 } 745 } 746 END { 747 print "# " lbytes " bytes " lblocks " blocks in " runs " runs " \ 748 minbytes " minbytes " maxbytes " maxbytes " minblocks " minblocks " \ 749 maxblocks " maxblocks " > "/dev/stderr" 750 }' 2> ${TMP_COUNT} 751 752 stat_add 753} 754 755############################# check_ignored ############################ 756# local shell function to check all stacks if they are not ignored 757######################################################################## 758check_ignored() 759{ 760 ${AWK} -F/ ' 761 BEGIN { 762 ignore = "'${IGNORED_STACKS}'" 763 # read in the ignore file 764 BUGNUM = "" 765 count = 0 766 new = 0 767 while ((getline line < ignore) > 0) { 768 if (line ~ "^#[0-9]+") { 769 BUGNUM = line 770 } else if (line ~ "^#") { 771 continue 772 } else if (line == "") { 773 continue 774 } else { 775 bugnum_array[count] = BUGNUM 776 # Create a regular expression for the ignored stack: 777 # replace * with % so we can later replace them with regular expressions 778 # without messing up everything (the regular expressions contain *) 779 gsub("\\*", "%", line) 780 # replace %% with .* 781 gsub("%%", ".*", line) 782 # replace % with [^/]* 783 gsub("%", "[^/]*", line) 784 # add ^ at the beginning 785 # add $ at the end 786 line_array[count] = "^" line "$" 787 count++ 788 } 789 } 790 } 791 { 792 match_found = 0 793 # Look for matching ignored stack 794 for (i = 0; i < count; i++) { 795 if ($0 ~ line_array[i]) { 796 # found a match 797 match_found = 1 798 bug_found = bugnum_array[i] 799 break 800 } 801 } 802 # Process result 803 if (match_found == 1 ) { 804 if (bug_found != "") { 805 print "IGNORED STACK (" bug_found "): " $0 806 } else { 807 print "IGNORED STACK: " $0 808 } 809 } else { 810 print "NEW STACK: " $0 811 new = 1 812 } 813 } 814 END { 815 exit new 816 }' 817 ret=$? 818 return $ret 819} 820 821############################### parse_log ############################## 822# local shell function to parse log file 823######################################################################## 824log_parse() 825{ 826 ${PARSE_LOGFILE} < ${LOGFILE} > ${TMP_STACKS} 827 echo "${SCRIPTNAME}: Processing log ${LOGNAME}:" > ${TMP_SORTED} 828 cat ${TMP_STACKS} | sort -u | check_ignored >> ${TMP_SORTED} 829 ret=$? 830 echo >> ${TMP_SORTED} 831 832 cat ${TMP_SORTED} | tee -a ${FOUNDLEAKS} 833 rm ${TMP_STACKS} ${TMP_SORTED} 834 835 return ${ret} 836} 837 838############################## cnt_total ############################### 839# local shell function to count total leaked bytes 840######################################################################## 841cnt_total() 842{ 843 echo "" 844 echo "TinderboxPrint:${OPT} Lk bytes: ${tbytes}" 845 echo "TinderboxPrint:${OPT} Lk blocks: ${tblocks}" 846 echo "TinderboxPrint:${OPT} # of runs: ${truns}" 847 echo "" 848} 849 850############################### run_ocsp ############################### 851# local shell function to run ocsp tests 852######################################################################## 853run_ocsp() 854{ 855 stat_clear 856 857 cd ${QADIR}/iopr 858 . ./ocsp_iopr.sh 859 ocsp_iopr_run 860 861 stat_print "Ocspclnt" 862} 863 864############################## run_chains ############################## 865# local shell function to run PKIX certificate chains tests 866######################################################################## 867run_chains() 868{ 869 stat_clear 870 871 LOGNAME="chains" 872 LOGFILE=${LOGDIR}/chains.log 873 874 . ${QADIR}/chains/chains.sh 875 876 stat_print "Chains" 877} 878 879############################## run_chains ############################## 880# local shell function to run memory leak tests 881# 882# NSS_MEMLEAK_TESTS - list of tests to run, if not defined before, 883# then is redefined to default list 884######################################################################## 885memleak_run_tests() 886{ 887 nss_memleak_tests="ssl_server ssl_client chains ocsp" 888 NSS_MEMLEAK_TESTS="${NSS_MEMLEAK_TESTS:-$nss_memleak_tests}" 889 890 for MEMLEAK_TEST in ${NSS_MEMLEAK_TESTS} 891 do 892 case "${MEMLEAK_TEST}" in 893 "ssl_server") 894 run_ciphers_server 895 ;; 896 "ssl_client") 897 run_ciphers_client 898 ;; 899 "chains") 900 run_chains 901 ;; 902 "ocsp") 903 run_ocsp 904 ;; 905 esac 906 done 907} 908 909################################# main ################################# 910 911memleak_init 912memleak_run_tests 913cnt_total 914memleak_cleanup 915 916