Add valgrind support to randpkt-test.sh.
authorDarius Davis <darius@vmware.com>
Wed, 23 May 2018 08:53:59 +0000 (18:53 +1000)
committerAnders Broman <a.broman58@gmail.com>
Wed, 30 May 2018 08:22:48 +0000 (08:22 +0000)
There's already valgrind support in fuzz-test.sh; This change simply clones the
relevant fragments of script into randpkt-test.sh, making very minor tweaks as
needed.  Valgrind support in randpkt-test.sh is enabled through the "-g"
command-line option, just like with fuzz-test.sh.

In my testing here, it seems MAX_LEAK could be reduced somewhat, but I don't
think that that belongs as part of this change; I've simply kept the MAX_LEAK
value from fuzz-test.sh.

While we're here, the last line of valgrind-wireshark.sh launches a subprocess,
and that shell then simply returns its exit code, so there is no need for the
shell to stick around.  So, let's use "exec" here to replace the shell with the
new process.

Testing Done: On Linux amd64, ran several iterations of randpkt-test.sh and
   fuzz-test.sh, both with and without the "-g" option.

Change-Id: I87cc63559dc2e66c42c905f46657ce40cabf0104
Reviewed-on: https://code.wireshark.org/review/27741
Reviewed-by: Anders Broman <a.broman58@gmail.com>
tools/randpkt-test.sh
tools/valgrind-wireshark.sh

index 8ba42019a2f789402a96f4a598e3cba0bd4faaf9..8d7b0b735a1cfcbbdb42378a17f9b64630e252de 100755 (executable)
@@ -10,6 +10,9 @@ TEST_TYPE="randpkt"
 # shellcheck source=tools/test-common.sh
 . `dirname $0`/test-common.sh || exit 1
 
+# Run under valgrind ?
+VALGRIND=0
+
 # Run under AddressSanitizer ?
 ASAN=$CONFIGURED_WITH_ASAN
 
@@ -17,12 +20,18 @@ ASAN=$CONFIGURED_WITH_ASAN
 # Uncomment to disable
 WIRESHARK_ABORT_ON_DISSECTOR_BUG="True"
 
+# The maximum permitted amount of memory leaked. Eventually this should be
+# worked down to zero, but right now that would fail on every single capture.
+# Only has effect when running under valgrind.
+MAX_LEAK=`expr 1024 \* 100`
+
 # To do: add options for file names and limits
-while getopts "ab:d:p:t:" OPTCHAR ; do
+while getopts "ab:d:gp:t:" OPTCHAR ; do
     case $OPTCHAR in
         a) ASAN=1 ;;
         b) WIRESHARK_BIN_DIR=$OPTARG ;;
         d) TMP_DIR=$OPTARG ;;
+        g) VALGRIND=1 ;;
         p) MAX_PASSES=$OPTARG ;;
         t) PKT_TYPES=$OPTARG ;;
     esac
@@ -36,12 +45,24 @@ ws_check_exec "$TSHARK" "$RANDPKT" "$DATE" "$TMP_DIR"
 
 [[ -z "$PKT_TYPES" ]] && PKT_TYPES=$($RANDPKT -h | awk '/^\t/ {print $1}')
 
-# TShark arguments (you won't have to change these)
-# n Disable network object name resolution
-# V Print a view of the details of the packet rather than a one-line summary of the packet
-# x Cause TShark to print a hex and ASCII dump of the packet data after printing the summary or details
-# r Read packet data from the following infile
-declare -a TSHARK_ARGS=("-nVxr" "-nr")
+if [ $VALGRIND -eq 1 ]; then
+    RUNNER="`dirname $0`/valgrind-wireshark.sh"
+    COMMON_ARGS="-b $WIRESHARK_BIN_DIR $COMMON_ARGS"
+    declare -a RUNNER_ARGS=("" "-T")
+    # Valgrind requires more resources, so permit 1.5x memory and 3x time
+    # (1.5x time is too small for a few large captures in the menagerie)
+    MAX_CPU_TIME=`expr 3 \* $MAX_CPU_TIME`
+    MAX_VMEM=`expr 3 \* $MAX_VMEM / 2`
+else
+    # Not using valgrind, use regular tshark.
+    # TShark arguments (you won't have to change these)
+    # n Disable network object name resolution
+    # V Print a view of the details of the packet rather than a one-line summary of the packet
+    # x Cause TShark to print a hex and ASCII dump of the packet data after printing the summary or details
+    # r Read packet data from the following infile
+    RUNNER="$TSHARK"
+    declare -a RUNNER_ARGS=("-nVxr" "-nr")
+fi
 RANDPKT_ARGS="-b 2000 -c 5000"
 
 if [ $ASAN -ne 0 ]; then
@@ -55,8 +76,8 @@ HOWMANY="forever"
 if [ $MAX_PASSES -gt 0 ]; then
     HOWMANY="$MAX_PASSES passes"
 fi
-echo -n "Running $TSHARK with args: "
-printf "\"%s\" " "${TSHARK_ARGS[@]}"
+echo -n "Running $RUNNER with args: "
+printf "\"%s\" " "${RUNNER_ARGS[@]}"
 echo "($HOWMANY)"
 echo "Running $RANDPKT with args: $RANDPKT_ARGS"
 echo ""
@@ -77,13 +98,14 @@ while [ $PASS -lt $MAX_PASSES -o $MAX_PASSES -lt 1 ] ; do
         echo -n "    $PKT_TYPE: "
 
         DISSECTOR_BUG=0
+        VG_ERR_CNT=0
 
         "$RANDPKT" $RANDPKT_ARGS -t $PKT_TYPE $TMP_DIR/$TMP_FILE \
             > /dev/null 2>&1
 
-       for ARGS in "${TSHARK_ARGS[@]}" ; do
+       for ARGS in "${RUNNER_ARGS[@]}" ; do
             echo -n "($ARGS) "
-           echo -e "Command and args: $TSHARK $ARGS\n" > $TMP_DIR/$ERR_FILE
+           echo -e "Command and args: $RUNNER $ARGS\n" > $TMP_DIR/$ERR_FILE
 
             # Run in a child process with limits.
             (
@@ -103,17 +125,35 @@ while [ $PASS -lt $MAX_PASSES -o $MAX_PASSES -lt 1 ] ; do
                     ulimit -S -v $MAX_VMEM
                 fi
 
-                "$TSHARK" $ARGS $TMP_DIR/$TMP_FILE \
+                "$RUNNER" $ARGS $TMP_DIR/$TMP_FILE \
                     > /dev/null 2>> $TMP_DIR/$ERR_FILE
             )
             RETVAL=$?
+
+            if [ $VALGRIND -eq 1 ]; then
+                VG_ERR_CNT=`grep "ERROR SUMMARY:" $TMP_DIR/$ERR_FILE | cut -f4 -d' '`
+                VG_DEF_LEAKED=`grep "definitely lost:" $TMP_DIR/$ERR_FILE | cut -f7 -d' ' | tr -d ,`
+                VG_IND_LEAKED=`grep "indirectly lost:" $TMP_DIR/$ERR_FILE | cut -f7 -d' ' | tr -d ,`
+                VG_TOTAL_LEAKED=`expr $VG_DEF_LEAKED + $VG_IND_LEAKED`
+                if [ $RETVAL -ne 0 ] ; then
+                    echo "General Valgrind failure."
+                    VG_ERR_CNT=1
+                elif [ "$VG_TOTAL_LEAKED" -gt "$MAX_LEAK" ] ; then
+                    echo "Definitely + indirectly ($VG_DEF_LEAKED + $VG_IND_LEAKED) exceeds max ($MAX_LEAK)."
+                    echo "Definitely + indirectly ($VG_DEF_LEAKED + $VG_IND_LEAKED) exceeds max ($MAX_LEAK)." >> $TMP_DIR/$ERR_FILE
+                    VG_ERR_CNT=1
+                fi
+                if grep -q "Valgrind cannot continue" $TMP_DIR/$ERR_FILE; then
+                    echo "Valgrind unable to continue."
+                    VG_ERR_CNT=-1
+                fi
+            fi
            if [ $RETVAL -ne 0 ] ; then break ; fi
         done
         grep -i "dissector bug" $TMP_DIR/$ERR_FILE \
             > /dev/null 2>&1 && DISSECTOR_BUG=1
 
-        if [ $RETVAL -ne 0 -o $DISSECTOR_BUG -ne 0 ] ; then
-
+        if [ $RETVAL -ne 0 -o $DISSECTOR_BUG -ne 0 -o $VG_ERR_CNT -ne 0 ] ; then
             ws_exit_error
         fi
         echo " OK"
index 17b7d350f7a8e9846d95bd5feb801654c3404b06..b598c40c30853c455863c515c5059473d6dfaccd 100755 (executable)
@@ -130,4 +130,4 @@ if [ "$VERBOSE" != "" ];then
   echo -e "\n$cmdline\n"
 fi
 
-$cmdline > /dev/null
+exec $cmdline > /dev/null