summaryrefslogtreecommitdiffstats
path: root/taskcluster/scripts/builder/hazard-analysis.sh
blob: d3e57474281112161de7cda3250d8860ce232b63 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#!/bin/bash -ex

[ -n "$WORKSPACE" ]
[ -n "$MOZ_OBJDIR" ]
[ -n "$GECKO_DIR" ]

HAZARD_SHELL_OBJDIR=$WORKSPACE/obj-haz-shell
JS_SRCDIR=$GECKO_DIR/js/src
ANALYSIS_SRCDIR=$JS_SRCDIR/devtools/rootAnalysis

export CC="$TOOLTOOL_DIR/gcc/bin/gcc"
export CXX="$TOOLTOOL_DIR/gcc/bin/g++"

PYTHON=python2.7
if ! which $PYTHON; then
    PYTHON=python
fi


function check_commit_msg () {
    ( set +e;
    if [[ -n "$AUTOMATION" ]]; then
        hg --cwd "$GECKO_DIR" log -r. --template '{desc}\n' | grep -F -q -- "$1"
    else
        echo -- "$SCRIPT_FLAGS" | grep -F -q -- "$1"
    fi
    )
}

if check_commit_msg "--dep"; then
    HAZ_DEP=1
fi

function build_js_shell () {
    # Must unset MOZ_OBJDIR and MOZCONFIG here to prevent the build system from
    # inferring that the analysis output directory is the current objdir. We
    # need a separate objdir here to build the opt JS shell to use to run the
    # analysis.
    (
    unset MOZ_OBJDIR
    unset MOZCONFIG
    ( cd $JS_SRCDIR; autoconf-2.13 )
    if [[ -z "$HAZ_DEP" ]]; then
        [ -d $HAZARD_SHELL_OBJDIR ] && rm -rf $HAZARD_SHELL_OBJDIR
    fi
    mkdir -p $HAZARD_SHELL_OBJDIR || true
    cd $HAZARD_SHELL_OBJDIR
    $JS_SRCDIR/configure --enable-optimize --disable-debug --enable-ctypes --enable-nspr-build --without-intl-api --with-ccache
    make -j4
    ) # Restore MOZ_OBJDIR and MOZCONFIG
}

function configure_analysis () {
    local analysis_dir
    analysis_dir="$1"

    if [[ -z "$HAZ_DEP" ]]; then
        [ -d "$analysis_dir" ] && rm -rf "$analysis_dir"
    fi

    mkdir -p "$analysis_dir" || true
    (
        cd "$analysis_dir"
        cat > defaults.py <<EOF
js = "$HAZARD_SHELL_OBJDIR/dist/bin/js"
analysis_scriptdir = "$ANALYSIS_SRCDIR"
objdir = "$MOZ_OBJDIR"
source = "$GECKO_DIR"
sixgill = "$TOOLTOOL_DIR/sixgill/usr/libexec/sixgill"
sixgill_bin = "$TOOLTOOL_DIR/sixgill/usr/bin"
EOF

        cat > run-analysis.sh <<EOF
#!/bin/sh
if [ \$# -eq 0 ]; then
  set gcTypes
fi
export ANALYSIS_SCRIPTDIR="$ANALYSIS_SRCDIR"
exec "$ANALYSIS_SRCDIR/analyze.py" "\$@"
EOF
        chmod +x run-analysis.sh
    )
}

function run_analysis () {
    local analysis_dir
    analysis_dir="$1"
    local build_type
    build_type="$2"

    if [[ -z "$HAZ_DEP" ]]; then
        [ -d $MOZ_OBJDIR ] && rm -rf $MOZ_OBJDIR
    fi

    (
        cd "$analysis_dir"
        $PYTHON "$ANALYSIS_SRCDIR/analyze.py" --buildcommand="$GECKO_DIR/testing/mozharness/scripts/spidermonkey/build.${build_type}"
    )
}

function grab_artifacts () {
    local analysis_dir
    analysis_dir="$1"
    local artifacts
    artifacts="$2"

    (
        cd "$analysis_dir"
        ls -lah

        # Do not error out if no files found
        shopt -s nullglob
        set +e
        for f in *.txt *.lst; do
            gzip -9 -c "$f" > "${artifacts}/$f.gz"
        done

        # Check whether the user requested .xdb file upload in the top commit comment
        if check_commit_msg "--upload-xdbs"; then
            HAZ_UPLOAD_XDBS=1
        fi

        if [ -n "$HAZ_UPLOAD_XDBS" ]; then
            for f in *.xdb; do
                bzip2 -c "$f" > "${artifacts}/$f.bz2"
            done
        fi
    )
}

function check_hazards () {
    (
    set +e
    NUM_HAZARDS=$(grep -c 'Function.*has unrooted.*live across GC call' "$1"/rootingHazards.txt)
    NUM_UNSAFE=$(grep -c '^Function.*takes unsafe address of unrooted' "$1"/refs.txt)
    NUM_UNNECESSARY=$(grep -c '^Function.* has unnecessary root' "$1"/unnecessary.txt)

    set +x
    echo "TinderboxPrint: rooting hazards<br/>$NUM_HAZARDS"
    echo "TinderboxPrint: unsafe references to unrooted GC pointers<br/>$NUM_UNSAFE"
    echo "TinderboxPrint: unnecessary roots<br/>$NUM_UNNECESSARY"

    if [ $NUM_HAZARDS -gt 0 ]; then
        echo "TEST-UNEXPECTED-FAIL $NUM_HAZARDS hazards detected" >&2
        echo "TinderboxPrint: documentation<br/><a href='https://wiki.mozilla.org/Javascript:Hazard_Builds'>static rooting hazard analysis failures</a>, visit \"Inspect Task\" link for hazard details"
        exit 1
    fi
    )
}