Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TSsan error when using AwaitWithTimeout with multiple waiters #299

Closed
taekahn opened this issue Apr 29, 2019 · 3 comments
Closed

TSsan error when using AwaitWithTimeout with multiple waiters #299

taekahn opened this issue Apr 29, 2019 · 3 comments
Assignees

Comments

@taekahn
Copy link

taekahn commented Apr 29, 2019

Summary

Creating two threads, both calling AwaitWithTimeout with a Condition, and then setting the condition to true produces a TSan error

Per #217 and the linked issue google/sanitizers#953 I tried running with report_atomic_races=0, but still see the error.

Code to reproduce

TEST(Concurrency, express_tsan_issue_with_multiple_waiters)
{
  std::queue<int> shared_queue;
  absl::Mutex shared_mutex;

  auto work = [&shared_queue, &shared_mutex]() {
      auto start = absl::Now();
      auto duration = absl::Seconds(3);
      while (absl::Now() - start < duration) {
        absl::MutexLock lock(&shared_mutex);
        shared_mutex.AwaitWithTimeout(
            absl::Condition(+[](std::queue<int>* queue) { return !queue->empty(); }, &shared_queue),
            absl::Seconds(1));
        if (!shared_queue.empty()) shared_queue.pop();
      }
  };

  auto t1 = std::async(std::launch::async, work);
  auto t2 = std::async(std::launch::async, work);

  {
    absl::MutexLock lock(&shared_mutex);
    shared_queue.push(5);
  }
}

Error produced (shortened)

==================
WARNING: ThreadSanitizer: data race (pid=14)
  Read of size 8 at 0x7f68b5aaf100 by thread T1:
    #0 absl::Mutex::Block(absl::base_internal::PerThreadSynch*) external/com_google_absl/absl/synchronization/mutex.cc:1092 
    #1 absl::Mutex::AwaitCommon(absl::Condition const&, absl::synchronization_internal::KernelTimeout) external/com_google_absl/absl/synchronization/mutex.cc:1550 
    #2 absl::Mutex::AwaitWithDeadline(absl::Condition const&, absl::Time) external/com_google_absl/absl/synchronization/mutex.cc:1531
    #3 absl::Mutex::AwaitWithTimeout(absl::Condition const&, absl::Duration) external/com_google_absl/absl/synchronization/mutex.cc:1519 

  Previous write of size 8 at 0x7f68b5aaf100 by thread T2:
    #0 Dequeue external/com_google_absl/absl/synchronization/mutex.cc:969 
    #1 absl::Mutex::TryRemove(absl::base_internal::PerThreadSynch*) external/com_google_absl/absl/synchronization/mutex.cc:1057
    #2 absl::Mutex::Block(absl::base_internal::PerThreadSynch*) external/com_google_absl/absl/synchronization/mutex.cc:1090
    #3 absl::Mutex::AwaitCommon(absl::Condition const&, absl::synchronization_internal::KernelTimeout) external/com_google_absl/absl/synchronization/mutex.cc:1550
    #4 absl::Mutex::AwaitWithDeadline(absl::Condition const&, absl::Time) external/com_google_absl/absl/synchronization/mutex.cc:1531
    #5 absl::Mutex::AwaitWithTimeout(absl::Condition const&, absl::Duration) external/com_google_absl/absl/synchronization/mutex.cc:1519

SUMMARY: ThreadSanitizer: data race external/com_google_absl/absl/synchronization/mutex.cc:1092 in absl::Mutex::Block(absl::base_internal::PerThreadSynch*)
==================

Environment

bazel 0.23
gcc 8.2
abseil commit 0dffca4


The test pretty reliably produces the TSan error, but it does spuriously pass on occasion.
Any help / points in the right direction appreciated.

@derekmauro
Copy link
Member

I didn't try your example, but I looked into building Abseil with TSAN correctly and here is what I've determined:

  • Abseil+TSAN probably isn't going to work with GCC at all. absl::Mutex relies on https://github.com/abseil/abseil-cpp/blob/master/absl/base/internal/tsan_mutex_interface.h to tell TSAN about its internals, and according to my testing only Clang seems to have <sanitizer/tsan_interface.h>. However, you don't seem to get any warning about this when you try to build with GCC.
  • You must build with -DTHREAD_SANITIZER and -DDYNAMIC_ANNOTATIONS_ENABLED=1. With Bazel, you would pass --copt=-DTHREAD_SANITIZER and --copt=-DDYNAMIC_ANNOTATIONS_ENABLED=1 on the command line.
  • It also seems like TSAN_OPTIONS=report_atomic_races=0 is necessary (--test_env="TSAN_OPTIONS=report_atomic_races=0" when running under bazel test)

None of this is ideal. We should be able to automatically detect when Abseil is being compiled with TSAN and set the appropriate defines accordingly, and error when the appropriate interfaces aren't available. I'll look into doing this.

@derekmauro derekmauro self-assigned this May 5, 2019
@GregBowyer
Copy link

For what it is worth Gcc 8.3 & 9.1 for me does include the tsan interface file, so it might be worth making sure this doesnt get broken for newer versions of GCC?

@derekmauro
Copy link
Member

This should be fixed by bb7be49.

copybara-service bot pushed a commit that referenced this issue Sep 11, 2024
  - d1397431006ea1362a5914d4a90b265d0c7c6f2c Update zoneinfo files to 2024b (#300) by Bradley White <14679271+devbww@users.noreply.github.com>
  - 8bdbd840e97ff32e17f25db85c82589819ad3352 Fix mingw compiler error due to missing function declarat... by Biswapriyo Nath <nathbappai@gmail.com>
  - 6624659e01e73e41527d6b27036e9f79a556560f Add GitHub Actions CI (#299) by Derek Mauro <761129+derekmauro@users.noreply.github.com>

PiperOrigin-RevId: 673451051
Change-Id: Id39f2186bbdcb802d4fc4c5e21207c6f3709c56f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants
@GregBowyer @derekmauro @taekahn and others