-
Notifications
You must be signed in to change notification settings - Fork 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