This is an archive of the discontinued LLVM Phabricator instance.

[tsan][clang] Introduce a function attribute to disable TSan checking at run time
ClosedPublic

Authored by zaks.anna on Oct 20 2016, 5:38 PM.

Details

Summary

This introduces a function annotation that disables TSan checking for the function at run time. The benefit over attribute((no_sanitize("thread"))) is that the accesses within the callees will also be suppressed.

The motivation for this attribute is a guarantee given by the objective C language that the calls to the reference count decrement and object deallocation will be synchronized. To model this properly, we would need to intercept all ref count decrement calls (which are very common in ObjC due to use of ARC) and also every single message send. Instead, we propose to just ignore all accesses made from within dealloc at run time. The main downside is that this still does not introduce any synchronization, which means we might still report false positives if the code that relies on this synchronization is not executed from within dealloc. However, we have not seen this in practice so far and think these cases will be very rare.

(This problem is similar in nature to https://reviews.llvm.org/D21609; unfortunately, the same solution does not apply here.)

This is used by https://reviews.llvm.org/D25858.

Diff Detail

Event Timeline

zaks.anna updated this revision to Diff 75374.Oct 20 2016, 5:38 PM
zaks.anna retitled this revision from to [tsan] Introduce a function attribute to disable TSan checking at run time.
zaks.anna updated this object.
zaks.anna added reviewers: kcc, kubamracek, dvyukov.
zaks.anna added a subscriber: cfe-commits.
zaks.anna retitled this revision from [tsan] Introduce a function attribute to disable TSan checking at run time to [tsan][clang] Introduce a function attribute to disable TSan checking at run time.Oct 20 2016, 5:47 PM
zaks.anna updated this object.
kubamracek edited edge metadata.Oct 26 2016, 7:22 PM

Does this also disable checking for the compiler generated .cxx_destruct Obj-C methods? Can we add a testcase both here and into compiler-rt?

dvyukov added inline comments.Oct 30 2016, 6:51 PM
lib/CodeGen/CodeGenFunction.cpp
734

This is unpleasant. We had recursive ignores in the old Valgrind-based tsan, but managed to not reintroduce them in the new tsan so far. But I also don't see any better solution.

738

Can we do this check right in the tsan pass? Or this information is already lost there?

739

Also do:

Fn->removeFnAttr(llvm::Attribute::SanitizeThread);

That's what will effectively happen. And it will allow to simplify the other patch.

Thanks for the review! I'll submit the updated patches soon.

zaks.anna updated this revision to Diff 76643.Nov 1 2016, 3:55 PM
zaks.anna edited edge metadata.

Addressed the review comments.

I also added ObjC +initialize method to the list because TSan does not observe the guaranteed synchronization between +initialize and initial object accesses.

dvyukov added inline comments.Nov 6 2016, 7:59 PM
test/CodeGen/sanitize-thread-no-checking-at-run-time.m
2

Are you sure this is the right location for the test?
test/CodeGen does not seem to contain any tests, only subdirs.

36

Does this check actually work?
I would expect that sanitize_thread, if present, will be eaten by the previous line.
Not sure what's the best way to fix it. What is the exact list of attributes on the previous line? Maybe we can just specify them all without using {{.*}}?

zaks.anna marked 4 inline comments as done.Nov 9 2016, 6:13 PM
zaks.anna added inline comments.
test/CodeGen/sanitize-thread-no-checking-at-run-time.m
2

You are looking at the llvm/test/CodeGen instead of the clang/test/CodeGen. The latter contains individual test files and I think it's the right place for the test.

36

Listing all attributes won't be low maintenance as more attributes could be added. Here is the list we have now:

attributes #0 = { nounwind sanitize_thread "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-features"="+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }

I could check that there are double quotes after nounwind:
TSAN: attributes [[ATTR]] = { nounwind "{{.*}} "sanitize_thread_no_checking_at_run_time" {{.*}} }

Alternatively, I could drop this aspect of the test altogether since I have an assert in the llvm pass.

zaks.anna updated this revision to Diff 77435.Nov 9 2016, 6:14 PM
zaks.anna marked an inline comment as done.
dvyukov accepted this revision.Nov 10 2016, 9:11 PM
dvyukov edited edge metadata.

Alternatively, I could drop this aspect of the test altogether since I have an assert in the llvm pass.

Dropping the check is fine in this case.

This revision is now accepted and ready to land.Nov 10 2016, 9:11 PM
This revision was automatically updated to reflect the committed changes.