summaryrefslogtreecommitdiff
path: root/one-off
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2015-10-11 13:08:56 +0200
committerPeter Wu <peter@lekensteyn.nl>2015-10-11 13:23:18 +0200
commitba36cb17a8b4a4ada245b6c1f707b33f125a2eae (patch)
treedc3993944ba9207ea2b45064cd6038e0881082d2 /one-off
parent7efac0d9d0a8fa71a33565f62401a3b62b6c5372 (diff)
downloadwireshark-notes-ba36cb17a8b4a4ada245b6c1f707b33f125a2eae.tar.gz
one-off/find-experts-in-tree: added
Add tool that leverages clang-query to find expert info callers which are behind an if(tree).
Diffstat (limited to 'one-off')
-rwxr-xr-xone-off/find-expert-in-tree99
1 files changed, 99 insertions, 0 deletions
diff --git a/one-off/find-expert-in-tree b/one-off/find-expert-in-tree
new file mode 100755
index 0000000..3ee9a5f
--- /dev/null
+++ b/one-off/find-expert-in-tree
@@ -0,0 +1,99 @@
+#!/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).
+# Author: Peter Wu <peter@lekensteyn.nl>
+
+# 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'
+# Use this for analysis:
+awk '/"[r]oot" binds here/{i=3} !/clang-query/&&i>0{print;i--}' scan.log | less -R
+EOF
+
+# vim: set sw=4 ts=4 et: