This is an archive of the discontinued LLVM Phabricator instance.

[tsan] Introduce a "ignore_interceptors_accesses" option
ClosedPublic

Authored by kubamracek on Dec 3 2015, 7:03 AM.

Details

Summary

On OS X, TSan already passes all unit and lit tests, but for real-world applications (even very simple ones), we currently produce a lot of false positive reports about data races. This makes TSan useless at this point, because the noise dominates real bugs. I'd like to introduce a runtime flag, "ignore_interceptors_accesses", off by default, which will make TSan ignore all memory accesses that happen from interceptors. This will significantly lower the coverage and miss a lot of bugs, but it eliminates most of the current false positives on OS X.

The false positives are mostly coming from system libraries that use custom synchronization (atomics) and/or synchronize via APIs that we haven't written interceptors for yet. This flag, "ignore_interceptors_accesses", is intended as a temporary bring-up tool, so that TSan can actually be used on a GUI app.

Diff Detail

Repository
rL LLVM

Event Timeline

kubamracek updated this revision to Diff 41751.Dec 3 2015, 7:03 AM
kubamracek retitled this revision from to [tsan] Introduce a "ignore_interceptors_accesses" option.
kubamracek updated this object.
kubamracek added reviewers: dvyukov, kcc, glider, samsonov.
kubamracek added subscribers: llvm-commits, zaks.anna.
dvyukov edited edge metadata.Dec 3 2015, 11:27 AM

This flag, "ignore_interceptors_accesses", is intended as a temporary bring-up tool, so that TSan can actually be used on a GUI app.

Do we need to submit it then? How long will it live? What is supposed to be a permanent solution?

Can we have a test for these false positives? I am not sure whether it is possible to run GUI tests within lit tests. is it possible to use these libraries without GUI? It would be useful to have a test that just invokes some fat functions from system libraries and test that we don't report any races.

I think we want to use something along the lines of called_from_lib suppressions. Or we want to ignore mops from all libraries? I guess we want to handle memory access coming at least from the main binary, right?

Also I would prefer to pass the flag under the covers. This change is too pervasive, while all we need is:

ScopedInterceptor::ScopedInterceptor(...) {
  if (...) {
    ThreadIgnoreBegin(thr_, pc_);
    unignore_ = true;
  }

ScopedInterceptor::~ScopedInterceptor() {
  if (unignore_)
      ThreadIgnoreEnd(thr_, pc_);
kubamracek updated this revision to Diff 44009.Jan 5 2016, 8:39 AM
kubamracek edited edge metadata.

Updating patch to only enable/disable tracking of memory accesses in ScopedInterceptor. Adding a test case.

dvyukov added inline comments.Jan 9 2016, 7:00 AM
lib/sanitizer_common/sanitizer_common_interceptors.inc
3311 ↗(On Diff #44009)

I think you need to put it before REAL(_exit), because it is no-return. Though, it is probably don't matter much.

lib/tsan/rtl/tsan_interceptors.cc
2155 ↗(On Diff #44009)

Why is this a user callback?

kubamracek added inline comments.Jan 9 2016, 10:22 AM
lib/tsan/rtl/tsan_interceptors.cc
2155 ↗(On Diff #44009)

It ends up calling ThreadFinalize, which expects ignores to be disabled (check that ignore_reads_and_writes==0). Suggestions to handle this better?

dvyukov added inline comments.Jan 9 2016, 11:58 PM
lib/tsan/rtl/tsan_interceptors.cc
2155 ↗(On Diff #44009)

How does libc function call ThreadFinalize (stack trace)? Does it happen for pthread_kill of pthread_self?

I was mistaken about pthread_kill, it doesn't need to be wrapped with USER_CALLBACK_START/END.

dvyukov accepted this revision.Jan 12 2016, 3:28 AM
dvyukov edited edge metadata.

LGTM if you move REAL(_exit). Code after _exit just looks strange.

This revision is now accepted and ready to land.Jan 12 2016, 3:28 AM
This revision was automatically updated to reflect the committed changes.