- Notifications
You must be signed in to change notification settings - Fork 1.1k
ThreadSanitizerOnAndroid
This page describes how to use ThreadSanitizer on Android devices. The instructions are raw. Ideally all that is integrated into llvm/android build systems. But that's what we have now.
download aosp_master by following instructions in https://source.android.com/source/downloading.html
download compiler-rt from github https://github.com/llvmmirror/compilerrt
1. replace aosp_master/external/compiler_rt with compilerrt in upstream.
$mv aosp_master/external/compiler_rt aosp_master_compiler_rt $cd aosp_master/external $ln s ../../compiler_rt compiler_rt 2. copy build files from aosp_master compiler_rt to upstream compiler_rt.
$cd aosp_master_compiler_rt $find . name Android.bp ./Android.bp ./lib/tsan/Android.bp ./lib/profile/Android.bp ./lib/sanitizer_common/Android.bp ./lib/sanitizer_common/tests/Android.bp ./lib/interception/Android.bp ./lib/ubsan/Android.bp ./lib/asan/Android.bp ./lib/lsan/Android.bp copy all Android.bp from aosp_master_compiler_rt to corresponding directories in upstream compiler_rt. except lib/asan/Android.bp (because it has a wrap file which doesn’t appear in upstream)
$ cp Android.bp ../aosp_master/external/compilerrt/ $ cp lib/tsan/Android.bp ../aosp_master/external/compilerrt/lib/tsan/ $ cp lib/profile/Android.bp ../aosp_master/external/compilerrt/lib/profile/ $ cp lib/sanitizer_common/Android.bp ../aosp_master/external/compilerrt/lib/sanitizer_common/ $ cp lib/interception/Android.bp ../aosp_master/external/compilerrt/lib/interception/ $ cp lib/ubsan/Android.bp ../aosp_master/external/compilerrt/lib/ubsan/ $ cp lib/lsan/Android.bp ../aosp_master/external/compilerrt/lib/lsan/ 3. change build files add following lines in lib/tsan/Android.bp, and remove tests build:
tsan_rtl_cppflags2 = [ "std=c++11", "Wall", "Werror", "Wnounusedparameter", "Wnononvirtualdtor", "fnortti", "fnobuiltin", "DTSAN_CONTAINS_UBSAN=0", ] cc_library_shared { name: "libtsan_shared", include_dirs: ["external/compilerrt/lib"], cppflags: tsan_rtl_cppflags2, srcs: [ "rtl/tsan_clock.cc", "rtl/tsan_flags.cc", "rtl/tsan_fd.cc", "rtl/tsan_ignoreset.cc", "rtl/tsan_interceptors.cc", "rtl/tsan_interface_ann.cc", "rtl/tsan_interface_atomic.cc", "rtl/tsan_interface.cc", "rtl/tsan_interface_java.cc", "rtl/tsan_md5.cc", "rtl/tsan_mman.cc", "rtl/tsan_mutex.cc", "rtl/tsan_mutexset.cc", "rtl/tsan_report.cc", "rtl/tsan_rtl.cc", "rtl/tsan_rtl_mutex.cc", "rtl/tsan_rtl_report.cc", "rtl/tsan_rtl_thread.cc", "rtl/tsan_stack_trace.cc", "rtl/tsan_stat.cc", "rtl/tsan_suppressions.cc", "rtl/tsan_symbolize.cc", "rtl/tsan_sync.cc", "rtl/tsan_platform_linux.cc", "rtl/tsan_platform_posix.cc", "rtl/tsan_new_delete.cc", "rtl/tsan_rtl_proc.cc", "rtl/tsan_rtl_aarch64.S", ], stl: "none", sanitize: { never: true, }, compile_multilib: "64", whole_static_libs: [ "libinterception_device", "libsan_device", ], shared_libs: ["libdl"], enabled: false, target: { android_arm64: { enabled: true, }, }, } remove tests build:
//cc_test_host { // name: "libtsan_unit_test", // // include_dirs: ["external/compilerrt/lib"], // local_include_dirs: ["rtl"], // cppflags: tsan_rtl_cppflags, // srcs: [ // "tests/unit/tsan_clock_test.cc", // "tests/unit/tsan_dense_alloc_test.cc", // "tests/unit/tsan_flags_test.cc", // "tests/unit/tsan_mman_test.cc", // "tests/unit/tsan_mutex_test.cc", // "tests/unit/tsan_mutexset_test.cc", // "tests/unit/tsan_shadow_test.cc", // "tests/unit/tsan_stack_test.cc", // "tests/unit/tsan_sync_test.cc", // "tests/unit/tsan_unit_test_main.cc", // "tests/unit/tsan_vector_test.cc", // ], // sanitize: { // never: true, // }, // compile_multilib: "64", // static_libs: [ // "libtsan", // "libubsan", // ], // host_ldlibs: [ // "lrt", // "ldl", // ], // target: { // darwin: { // enabled: false, // }, // }, //} // //cc_test_host { // name: "libtsan_rtl_test", // // include_dirs: ["external/compilerrt/lib"], // local_include_dirs: ["rtl"], // cppflags: tsan_rtl_cppflags, // srcs: [ // "tests/rtl/tsan_bench.cc", // "tests/rtl/tsan_mop.cc", // "tests/rtl/tsan_mutex.cc", // "tests/rtl/tsan_posix.cc", // "tests/rtl/tsan_string.cc", // "tests/rtl/tsan_test_util_posix.cc", // "tests/rtl/tsan_test.cc", // "tests/rtl/tsan_thread.cc", // ], // sanitize: { // never: true, // }, // compile_multilib: "64", // static_libs: [ // "libtsan", // "libubsan", // ], // host_ldlibs: [ // "lrt", // "ldl", // ], // target: { // darwin: { // enabled: false, // }, // }, //} add following lines in lib/interception/Android.bp:
cc_library_static { name: "libinterception_device", clang: true, sdk_version: "19", include_dirs: ["external/compilerrt/lib"], cppflags: [ "fvisibility=hidden", "fnoexceptions", "std=c++11", "Wall", "Werror", "Wnounusedparameter", ], srcs: [ "interception_linux.cc", "interception_mac.cc", "interception_type_test.cc", "interception_win.cc", ], stl: "none", sanitize: { never: true, }, compile_multilib: "both", } add following lines in lib/sanitizer_common/Android.bp:
cc_library_static { name: "libsan_device", clang: true, sdk_version: "19", include_dirs: ["external/compilerrt/lib"], cppflags: [ "fvisibility=hidden", "fnoexceptions", "std=c++11", "Wall", "Werror", "Wnononvirtualdtor", "Wnounusedparameter", ], srcs: [ // rtl "sanitizer_allocator.cc", "sanitizer_common.cc", "sanitizer_deadlock_detector1.cc", "sanitizer_deadlock_detector2.cc", "sanitizer_flags.cc", "sanitizer_flag_parser.cc", "sanitizer_libc.cc", "sanitizer_libignore.cc", "sanitizer_linux.cc", "sanitizer_mac.cc", "sanitizer_persistent_allocator.cc", "sanitizer_platform_limits_linux.cc", "sanitizer_platform_limits_posix.cc", "sanitizer_posix.cc", "sanitizer_printf.cc", "sanitizer_procmaps_common.cc", "sanitizer_procmaps_freebsd.cc", "sanitizer_procmaps_linux.cc", "sanitizer_procmaps_mac.cc", "sanitizer_stackdepot.cc", "sanitizer_stacktrace.cc", "sanitizer_stacktrace_printer.cc", "sanitizer_suppressions.cc", "sanitizer_symbolizer.cc", "sanitizer_symbolizer_libbacktrace.cc", "sanitizer_symbolizer_win.cc", "sanitizer_tls_get_addr.cc", "sanitizer_thread_registry.cc", "sanitizer_win.cc", // cdep "sanitizer_common_libcdep.cc", "sanitizer_coverage_libcdep.cc", "sanitizer_coverage_mapping_libcdep.cc", "sanitizer_linux_libcdep.cc", "sanitizer_posix_libcdep.cc", "sanitizer_stacktrace_libcdep.cc", "sanitizer_stoptheworld_linux_libcdep.cc", "sanitizer_symbolizer_libcdep.cc", "sanitizer_symbolizer_posix_libcdep.cc", "sanitizer_unwind_linux_libcdep.cc", "sanitizer_termination.cc", ], stl: "none", sanitize: { never: true, }, compile_multilib: "both", } 4. bulid libtsan_shared.so
$cd aosp_master $. build/envsetup.sh $lunch aosp_arm64userdebug $mmma external/compilerrt/lib/tsan j30 after building successfully, libtsan_shared.so for aarch64 is in aosp_master/out/target/product/generic_arm64/system/lib64/libtsan_shared.so
5. Link app with libtsan_shared.so Then you can use tsan by link libtsan_shared.so. Note that libtsan_shared.so only works with libc.so on N devices or built in aosp_master. So you may need to find a way to link libc.so built in aosp_master instead of the one running on device.
6. you may also need to build llvm-symbolizer and download llvm-symbolizer on device.
$mmma external/llvm/tools/llvm-symbolizer/ j20