  Static analysis is sound in theory, but an implementation may unsoundly fail
to analyze all of a program's code. Any such omission is a serious threat to
the validity of the tool's output. Our work is the first to measure the
prevalence of these omissions. Previously, researchers and analysts did not
know what is missed by static analysis, what sort of code is missed, or the
reasons behind these omissions. To address this gap, we ran 13 static analysis
tools and a dynamic analysis on 1000 Android apps. Any method in the dynamic
analysis but not in a static analysis is an unsoundness.
  Our findings include the following. (1) Apps built around external frameworks
challenge static analyzers. On average, the 13 static analysis tools failed to
capture 61% of the dynamically-executed methods. (2) A high level of precision
in call graph construction is a synonym for a high level of unsoundness; (3) No
existing approach significantly improves static analysis soundness. This
includes those specifically tailored for a given mechanism, such as DroidRA to
address reflection. It also includes systematic approaches, such as EdgeMiner,
capturing all callbacks in the Android framework systematically. (4) Modeling
entry point methods challenges call graph construction which jeopardizes
soundness.
