security/nss/tests/memleak/memleak.sh

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial