This is an archive of the discontinued LLVM Phabricator instance.

Fix LazyInitialization in tsan
ClosedPublic

Authored by ZijunZhao on Oct 13 2022, 4:10 PM.

Details

Summary

In Android, further initialization is always necessary whether preinit_array can be used.
LazyInitialize is needed regardless of .preinit_array support on platforms where runtime is loaded as dynamic library, e.g. Android.

Diff Detail

Event Timeline

ZijunZhao created this revision.Oct 13 2022, 4:10 PM
Herald added a project: Restricted Project. · View Herald TranscriptOct 13 2022, 4:10 PM
ZijunZhao requested review of this revision.Oct 13 2022, 4:10 PM
Herald added a project: Restricted Project. · View Herald TranscriptOct 13 2022, 4:10 PM
Herald added a subscriber: Restricted Project. · View Herald Transcript

This presumably disables DT_PREINIT_ARRAY on Android, but bionic supports DT_PREINIT_ARRAY.
What does this fix?

BIonic supports it, but the sanitizer cannot use it for Android because sanitizers are shared libraries on Android, and preinit array only works for excutables.

Worth a comment IMO.

I think this is a fix for LazyInitialize in the tsan_rtl.h - the logic there assumes that when preinit_array is always used whenever it can be used, and no further initialization is necessary. This assumption does not hold under -shared-libsan. IMO this should be fixed in LazyInitialize, not here.

ZijunZhao updated this revision to Diff 467949.Oct 14 2022, 3:49 PM
ZijunZhao retitled this revision from `SANITIZER_LINUX` should be `(SANITIZER_LINUX && !defined(__ANDROID__))` to Fix LazyInitialization in tsan.
ZijunZhao edited the summary of this revision. (Show Details)
vitalybuka added inline comments.
compiler-rt/lib/tsan/rtl/tsan_rtl.h
681–682

should we instead define SANITIZER_CAN_USE_PREINIT_ARRAY=0 for ANDROID ?

vitalybuka added inline comments.Oct 14 2022, 4:34 PM
compiler-rt/lib/tsan/rtl/tsan_rtl.h
681–682

I misread the patch.
I agree with @eugenis, removing #if is LGTM

This comment was removed by ZijunZhao.
compiler-rt/lib/tsan/rtl/tsan_rtl.h
681–682

@pirama considers that removing the #if does come with a performance cost and we don't want to regress other platforms. I agree with him, so I keep it.

pirama added inline comments.Oct 17 2022, 10:11 AM
compiler-rt/lib/tsan/rtl/tsan_rtl.h
681–682

Yes, it was my suggestion to add this only for Android to avoid the branch, even if it's marked UNLIKELY... (Partly because we don't have access to the to measure the actual impact).

Fine to remove the #if if @vitalybuka and @eugenis recommend it.

eugenis added inline comments.
compiler-rt/lib/tsan/rtl/tsan_rtl.h
681–682

This is only called in the interceptors. Perf impact should be insignificant. @dvyukov WDYT?

dvyukov added inline comments.Oct 19 2022, 10:32 PM
compiler-rt/lib/tsan/rtl/tsan_rtl.h
681–682

Yes, performance impact should be small.
But I am not following the commit description. The preinit_array function calls the very same Initialize function, so what is "further initialization"?

ZijunZhao added inline comments.Oct 20 2022, 11:57 AM
compiler-rt/lib/tsan/rtl/tsan_rtl.h
681–682

ohhh before the change, if SANITIZER_CAN_USE_PREINIT_ARRAY

if (UNLIKELY(!is_initialized))

will be skipped so we remove the #if

vitalybuka added inline comments.Oct 20 2022, 5:26 PM
OWNERS
1 ↗(On Diff #469306)

I guess you don't want to commit this file?

compiler-rt/lib/tsan/rtl/tsan_rtl.h
681–682

Probably the patch description should mention that
LazyInitialize is needed regardless of .preinit_array support on platforms where runtime is loaded as dynamic library, e.g. Android.

ZijunZhao edited the summary of this revision. (Show Details)
ZijunZhao marked an inline comment as done.
vitalybuka accepted this revision.Oct 21 2022, 2:18 PM
This revision is now accepted and ready to land.Oct 21 2022, 2:18 PM
dvyukov added inline comments.Oct 22 2022, 12:15 AM
compiler-rt/lib/tsan/rtl/tsan_rtl.h
681–682

Oh, sorry, I mis-read the question.
The performance impact should be small, but I did not mean to remove the ifdef entirely for all platforms.
It still affects small mem/str* functions. It normal builds they read just few bytes, or maybe even completely inlined. But in tsan build they impose all interceptor overheads. It's not that is_initialized check is super expensive on its own, but these bits sum up. So this LazyInitialize was a part of removing these overhead bits bit-by-bit.
Please restore the ifdef for other platforms.

ZijunZhao marked an inline comment as done.

@dvyukov yes, I restore the ifder for other platforms and is_initialized check is a must for Android.

dvyukov accepted this revision.Oct 24 2022, 11:34 AM
This revision was automatically updated to reflect the committed changes.