xamarin-android/build-tools/wrap.sh
Marek Habersack aaa37c3df9
[monodroid] Add native code static checkers and sanitizers (#5094)
Context: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1139593

Begin running Clang-based code analysis tools against our C++ codebase:

  * [`clang-tidy`][0] static analysis
  * [`ASAN`][1] and [`UBSAN`][2] runtime sanitizers, which can find
    some issues that cannot be detected by static analysis.

All of the required tools are shipped with the Android NDK, which 
currently ships the Clang 9 toolchain.

All of the tools require separate builds of the native code.
`clang-tidy` builds the entire codebase to generate an AST and then
analyze it, reporting possible errors, but it does not produce any
binaries.

The ASAN and UBSAN runtime sanitizers instrument the generated code in
numerous ways, which make runtime code much slower to execute, up to 3x
longer to run various tasks.  We now build our native code 4 additional
times, once for each sanitizer in both `Debug` and `Release` configs.
The output binaries have the `-checked+SANITIZER_NAME` infix added to
their name, e.g. `libmono-android-checked+asan.debug.so`.

The instrumented binaries will not be currently distributed to the end
users since they are intended for internal use.

Also added are two [`wrap.sh`][3] scripts, one for `ASAN` and the other
for `UBSAN`; both can be found in the `build-tools/wrap.sh/` directory.

The instrumented binaries can then be placed in the `.apk` instead of
the standard binaries by adding the following to the project file:

	<PropertyGroup>
	  <AndroidIncludeWrapSh Condition=" '$(UseASAN)' != '' Or '$(UseUBSAN)' != '' ">true</AndroidIncludeWrapSh>
	  <_AndroidCheckedBuild Condition=" '$(UseASAN)' != '' ">asan</_AndroidCheckedBuild>
	  <_AndroidCheckedBuild Condition=" '$(UseUBSAN)' != '' ">ubsan</_AndroidCheckedBuild>
	  <_ASANScript>../path/to/build-scripts/wrap.sh/asan.sh</_ASANScript>
	  <_UBSANScript>../path/to/build-scripts/wrap.sh/ubsan.sh</_UBSANScript>
	</PropertyGroup>

	<ItemGroup>
	  <AndroidNativeLibrary Include="$(_ASANScript)" Condition=" '$(UseASAN)' != '' ">
	    <Link>lib\arm64-v8a\wrap.sh</Link>
	  </AndroidNativeLibrary>
	  <AndroidNativeLibrary Include="$(_ASANScript)" Condition=" '$(UseASAN)' != '' ">
	    <Link>lib\armeabi-v7a\wrap.sh</Link>
	  </AndroidNativeLibrary>
	  <AndroidNativeLibrary Include="$(_ASANScript)" Condition=" '$(UseASAN)' != '' ">
	    <Link>lib\x86\wrap.sh</Link>
	  </AndroidNativeLibrary>
	  <AndroidNativeLibrary Include="$(_ASANScript)" Condition=" '$(UseASAN)' != '' ">
	    <Link>lib\x86_64\wrap.sh</Link>
	  </AndroidNativeLibrary>

	  <AndroidNativeLibrary Include="$(_UBSANScript)" Condition=" '$(UseUBSAN)' != '' ">
	    <Link>lib\arm64-v8a\wrap.sh</Link>
	  </AndroidNativeLibrary>
	  <AndroidNativeLibrary Include="$(_UBSANScript)" Condition=" '$(UseUBSAN)' != '' ">
	    <Link>lib\armeabi-v7a\wrap.sh</Link>
	  </AndroidNativeLibrary>
	  <AndroidNativeLibrary Include="$(_UBSANScript)" Condition=" '$(UseUBSAN)' != '' ">
	    <Link>lib\x86\wrap.sh</Link>
	  </AndroidNativeLibrary>
	  <AndroidNativeLibrary Include="$(_UBSANScript)" Condition=" '$(UseUBSAN)' != '' ">
	    <Link>lib\x86_64\wrap.sh</Link>
	  </AndroidNativeLibrary>
	</ItemGroup>


The `%(AndroidNativeLibrary.Link)` metadata value **must** be a valid
path to the native library directory inside the `.apk` since the
`wrap.sh` scripts are architecture-specific and are expected to be
found in specific directories by the Android loader.

The checked build is enabled by setting the `$(_AndroidCheckedBuild)`
MSBuild property to either `asan` or `ubsan`.

TODO: While "checked" versions of the native libraries are built, they
need to be *used* to be of full usefulness.  We still need to update CI
so that `Mono.Android-Tests` will be executed with `asan` or `ubsan`
enabled, to assert that future issues are not introduced.

[0]: https://releases.llvm.org/9.0.0/tools/clang/tools/extra/docs/clang-tidy/
[1]: https://releases.llvm.org/9.0.0/tools/clang/docs/AddressSanitizer.html
[2]: https://releases.llvm.org/9.0.0/tools/clang/docs/UndefinedBehaviorSanitizer.html
[3]: https://developer.android.com/ndk/guides/wrap-script
2020-10-13 16:01:41 -04:00
..
asan.sh [monodroid] Add native code static checkers and sanitizers (#5094) 2020-10-13 16:01:41 -04:00
ubsan.sh [monodroid] Add native code static checkers and sanitizers (#5094) 2020-10-13 16:01:41 -04:00