#!/bin/bash # Searches for functions adding expert items which are located in a if(tree) # guard. Tested using clang-query 3.7.0 (part of clang-tools-extra). # # Usage: # # Ensure that builddir and srcdir variables below are set # Ensure that compile_commands.json exists in builddir (see below). # Run `./find-expert-in-tree > scan.log` to write matching contexts to file # Use the displayed awk command for further processing (see bottom). # # Author: Peter Wu # path to builddir (should contain compile_commands.json, use # cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1) builddir=/tmp/wsbuild # path to source directory (will be scanned for files matching the function srcdir=/tmp/wireshark set -e -u # Condition which should match "if(tree)" and "if(tree && foo())" but not # "if(somefunc(tree))". cond=' hasCondition( # Do not use hasDescendant, it matches if(somefunc(tree)) too has( declRefExpr( hasType( asString("proto_tree *") ) ) ) ) ' # matches callers of expert_add_info[_format] and proto_tree_add_export[_format] body=' callee( functionDecl( hasAnyParameter( matchesName("eiindex") ) ) ) ' # print line with "if" matcher=" ifStmt( allOf( $cond, hasDescendant( callExpr($body) ) ) ) " # print line with caller (comment next line to enable it) : || \ matcher=" callExpr(allOf( $body, hasAncestor( ifStmt($cond) ) )) " matcher="$(sed '/^ *#/d;s/^ *//;s/ *$//' <<<"$matcher" | tr -d '\n')" args=( # Add this if you get an error about missing std headers #-extra-arg=-I/usr/lib/clang/3.7.0/include/ -p "$builddir" # Use "print" to show the full processed line. Use "diag" for a short line. # Use "dump" for a raw AST tree. -c "set output print" #-c "set output dump" -c "set output diag" -c "match ${matcher}" ) # Write file names matching the function names to a file (cache it in case this # script is interrupted). tmp=/tmp/files.txt [ -s "$tmp" ] || grep -rl --exclude=\* --include=\*.c --exclude-dir=asn1 "$srcdir" \ -e 'expert_add_info\|proto_tree_add_expert' > "$tmp" # Start the hunt! cat "$tmp" | #head | grep ssl| xargs -rt -P$(nproc) -n10 clang-query "${args[@]}" # add -t to xargs for verbose debugging (print commands as they are executed) # -P is used for parallel jobs # -n limits files per command. Use this to tune memory usage. rm "$tmp" cat <<'EOF' >&2 # Use this for analysis: awk '/"[r]oot" binds here/{i=3} !/clang-query/&&i>0{printf("%s\033[m\n", $0);i--}' scan.log | less -r EOF # vim: set sw=4 ts=4 et: