This is an archive of the discontinued LLVM Phabricator instance.

[tsan] Ignore memory accesses for libignored modules for "external" races
ClosedPublic

Authored by kubamracek on Mar 31 2017, 3:38 PM.

Details

Summary

On Darwin, the setting ignore_noninstrumented_modules is used to suppress false positives in code that users don't have control of. The recently added "external" API (which can be used to detect races on objects provided by system libraries, but the race is actually user's fault) ignores this flag and it can report issues in non-instrumented modules. This patch fixes that.

There's more discussion about this at https://reviews.llvm.org/D28836.

Diff Detail

Repository
rL LLVM

Event Timeline

kubamracek created this revision.Mar 31 2017, 3:38 PM
dvyukov edited edge metadata.Apr 2 2017, 1:57 AM

Wait, the external API was meant specifically to be used from non-instrumented libraries. Quoting you in D28836:

It might not be feasible/easy to recompile the library with TSan instrumentation... The idea of this patch is to allow a non-instrumented library to call into TSan runtime.

With this change it all become pointless. We annotate non-instrumented libraries and then ignore that. What am I missing?

Wait, the external API was meant specifically to be used from non-instrumented libraries. Quoting you in D28836:

It might not be feasible/easy to recompile the library with TSan instrumentation... The idea of this patch is to allow a non-instrumented library to call into TSan runtime.

With this change it all become pointless. We annotate non-instrumented libraries and then ignore that. What am I missing?

There's multiple scenarios, but a typical one can be: An API provider, which is shipped with the OS as a non-instrumented library, e.g. libcurl, adopts the TSan external API. Now users of libcurl don't need to recompile libcurl to detect when they're violating the libcurl's API threading rules. Even with the non-instrumented version of libcurl, TSan will report whenever you're using a CURL * object from multiple threads without synchronization. However, if you're using a 3rd party library (or a system library) that is *also non-instrumented* and uses libcurl, let's call it libftp, we would report bugs as well, even though they're not your bugs. And they could be real bugs (libftp has races) or false positives (libftp uses some atomic-based synchronization that is TSan-invisible), but they're still out of the user's control to fix. This patch silences reports that come from instrumented_module -> libftp -> libcurl, but still reports bugs from instrumented_module -> libcurl.

If the user actually wants to see races even in non-instrumented code (typically system libraries and 3rd party binary frameworks), they can always set the flag ignore_noninstrumented_modules back to 0.

dvyukov accepted this revision.Apr 21 2017, 6:05 AM
dvyukov added inline comments.
lib/tsan/rtl/tsan_external.cc
61 ↗(On Diff #93720)

I think I understand why I was confused. I assumed that caller_pc is literally caller pc. And caller can well point into the same library, and then this all does not make sense. But you seem to assume that caller_pc points user code (can be caller pc or several frames above that).

We now have include/sanitizer/tsan_interface.h, so please add __tsan_external_* functions there with proper comments that document these assumptions.

64 ↗(On Diff #93720)

Unrelated to this change, but why did we decide to use kSizeLog8? It would be more reasonable to use kSizeLog1. A library may need several different addresses to model several unrelated things and if the object is only 8 bytes, it won't be able to do so. Also if size of the object is only, say, 4 bytes, 8-byte access can lead to false positives.
Is there any reason to use 8? If not, please change it to 1.

This revision is now accepted and ready to land.Apr 21 2017, 6:05 AM
kubamracek added inline comments.Apr 21 2017, 10:22 AM
lib/tsan/rtl/tsan_external.cc
61 ↗(On Diff #93720)
kubamracek added inline comments.Apr 21 2017, 10:24 AM
lib/tsan/rtl/tsan_external.cc
64 ↗(On Diff #93720)
This revision was automatically updated to reflect the committed changes.