1#!/bin/bash
2
3# Copyright (c) 2012 The Chromium Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7# This is a small script for manually launching valgrind, along with passing
8# it the suppression file, and some helpful arguments (automatically attaching
9# the debugger on failures, etc).  Run it from your repo root, something like:
10#  $ sh ./tools/valgrind/valgrind.sh ./out/Debug/chrome
11#
12# This is mostly intended for running the chrome browser interactively.
13# To run unit tests, you probably want to run chrome_tests.sh instead.
14# That's the script used by the valgrind buildbot.
15
16export THISDIR=`dirname $0`
17
18setup_memcheck() {
19  RUN_COMMAND="valgrind"
20
21  # Prompt to attach gdb when there was an error detected.
22  DEFAULT_TOOL_FLAGS=("--db-command=gdb -nw %f %p" "--db-attach=yes" \
23                      # Keep the registers in gdb in sync with the code.
24                      "--vex-iropt-register-updates=allregs-at-mem-access" \
25                      # Overwrite newly allocated or freed objects
26                      # with 0x41 to catch inproper use.
27                      "--malloc-fill=41" "--free-fill=41" \
28                      # Increase the size of stacks being tracked.
29                      "--num-callers=30")
30}
31
32setup_tsan() {
33  RUN_COMMAND="valgrind-tsan.sh"
34  IGNORE_FILE="$THISDIR/tsan/ignores.txt"
35  DEFAULT_TOOL_FLAGS=("--announce-threads" "--pure-happens-before=yes" \
36                      "--ignore=$IGNORE_FILE")
37}
38
39setup_unknown() {
40  echo "Unknown tool \"$TOOL_NAME\" specified, the result is not guaranteed"
41  DEFAULT_TOOL_FLAGS=()
42}
43
44set -e
45
46if [ $# -eq 0 ]; then
47  echo "usage: <command to run> <arguments ...>"
48  exit 1
49fi
50
51TOOL_NAME="memcheck"
52declare -a DEFAULT_TOOL_FLAGS[0]
53
54# Select a tool different from memcheck with --tool=TOOL as a first argument
55TMP_STR=`echo $1 | sed 's/^\-\-tool=//'`
56if [ "$TMP_STR" != "$1" ]; then
57  TOOL_NAME="$TMP_STR"
58  shift
59fi
60
61if echo "$@" | grep "\-\-tool" ; then
62  echo "--tool=TOOL must be the first argument" >&2
63  exit 1
64fi
65
66case $TOOL_NAME in
67  memcheck*)  setup_memcheck "$1";;
68  tsan*)      setup_tsan;;
69  *)          setup_unknown;;
70esac
71
72
73SUPPRESSIONS="$THISDIR/$TOOL_NAME/suppressions.txt"
74
75CHROME_VALGRIND=`sh $THISDIR/locate_valgrind.sh`
76if [ "$CHROME_VALGRIND" = "" ]
77then
78  # locate_valgrind.sh failed
79  exit 1
80fi
81echo "Using valgrind binaries from ${CHROME_VALGRIND}"
82
83set -x
84PATH="${CHROME_VALGRIND}/bin:$PATH"
85# We need to set these variables to override default lib paths hard-coded into
86# Valgrind binary.
87export VALGRIND_LIB="$CHROME_VALGRIND/lib/valgrind"
88export VALGRIND_LIB_INNER="$CHROME_VALGRIND/lib/valgrind"
89
90# G_SLICE=always-malloc: make glib use system malloc
91# NSS_DISABLE_UNLOAD=1: make nss skip dlclosing dynamically loaded modules,
92# which would result in "obj:*" in backtraces.
93# NSS_DISABLE_ARENA_FREE_LIST=1: make nss use system malloc
94# G_DEBUG=fatal_warnings: make  GTK abort on any critical or warning assertions.
95# If it crashes on you in the Options menu, you hit bug 19751,
96# comment out the G_DEBUG=fatal_warnings line.
97#
98# GTEST_DEATH_TEST_USE_FORK=1: make gtest death tests valgrind-friendly
99#
100# When everyone has the latest valgrind, we might want to add
101#  --show-possibly-lost=no
102# to ignore possible but not definite leaks.
103
104G_SLICE=always-malloc \
105NSS_DISABLE_UNLOAD=1 \
106NSS_DISABLE_ARENA_FREE_LIST=1 \
107G_DEBUG=fatal_warnings \
108GTEST_DEATH_TEST_USE_FORK=1 \
109$RUN_COMMAND \
110  --trace-children=yes \
111  --leak-check=yes \
112  --suppressions="$SUPPRESSIONS" \
113  "${DEFAULT_TOOL_FLAGS[@]}" \
114  "$@"
115