Skip to content

ThreadSanitizerOnAndroid

Dmitry Vyukov edited this page Aug 19, 2016 · 3 revisions

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/llvm­mirror/compiler­rt

1. replace aosp_master/external/compiler_rt with compiler­rt 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/compiler­rt/ $ cp lib/tsan/Android.bp ../aosp_master/external/compiler­rt/lib/tsan/ $ cp lib/profile/Android.bp ../aosp_master/external/compiler­rt/lib/profile/ $ cp lib/sanitizer_common/Android.bp ../aosp_master/external/compiler­rt/lib/sanitizer_common/ $ cp lib/interception/Android.bp ../aosp_master/external/compiler­rt/lib/interception/ $ cp lib/ubsan/Android.bp ../aosp_master/external/compiler­rt/lib/ubsan/ $ cp lib/lsan/Android.bp ../aosp_master/external/compiler­rt/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",     "­Wno­unused­parameter",     "­Wno­non­virtual­dtor",     "­fno­rtti",     "­fno­builtin",     "­DTSAN_CONTAINS_UBSAN=0", ] cc_library_shared {     name: "libtsan_shared",     include_dirs: ["external/compiler­rt/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/compiler­rt/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/compiler­rt/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/compiler­rt/lib"],     cppflags: [         "­fvisibility=hidden",         "­fno­exceptions",         "­std=c++11",         "­Wall",         "­Werror",         "­Wno­unused­parameter",     ],     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/compiler­rt/lib"],     cppflags: [         "­fvisibility=hidden",         "­fno­exceptions",         "­std=c++11",         "­Wall",         "­Werror",         "­Wno­non­virtual­dtor",         "­Wno­unused­parameter",     ],     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_arm64­userdebug $mmma external/compiler­rt/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 
Clone this wiki locally