[llvm-bugs] [Bug 43228] New: Possible race in std::packaged_task

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Sep 5 08:02:11 PDT 2019


            Bug ID: 43228
           Summary: Possible race in std::packaged_task
           Product: libc++
           Version: unspecified
          Hardware: PC
                OS: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: All Bugs
          Assignee: unassignedclangbugs at nondot.org
          Reporter: labath at google.com
                CC: llvm-bugs at lists.llvm.org, mclow.lists at gmail.com

Running the following piece of code under tsan:
  auto task = std::make_shared<std::packaged_task<void()>>(
      [] { std::cout << "XXX" << std::endl; });
  std::thread([task] { (*task)(); }).detach();
Gives the following error message:
  Read of size 4 at 0x7b200000c2f0 by thread T5:
    #0 std::__1::__assoc_sub_state::__has_value() const
    #1 std::__1::packaged_task<void ()>::operator()()
    #2 main()::$_1::operator()() const
    #3 ...

  Previous write of size 4 at 0x7b200000c2f0 by main thread (mutexes: write
    #0 std::__1::__assoc_sub_state::__attach_future()
    #1 std::__1::future<void>::future(std::__tsan::__assoc_sub_state*)
    #2 std::__1::promise<void>::get_future()
    #3 std::__1::packaged_task<void ()>::get_future()
    #4 main()
    #5 ...

Looking at the code, once of the threads is doing "return __state_ &
__constructed", and the other one does a "__state_ |= __future_attached".

Now, I am not completely sure that what this snippet of code (obtained by
reduction from some code in LLDB) is doing is absolutely correct. I have looked
at the standard, and I could not find evidence either way (though it's possible
I am just not looking at the right place). However, there are some hints which
lead me to believe that this might not be intentional:
a) this code is "almost" race free. The only reason we are getting an error is
because the two threads are accessing different bits in the same integer. If
these were two integers everything would be ok.
b) cppreference.com
<https://en.cppreference.com/w/cpp/thread/promise/get_future> explicitly says
that promise::get_future does not race with promise::set_value. That said, I am
not sure what is the basis of this claim of their, and also cppreference is
suspiciously quiet about the packaged_task class.

I'd appreciate it if someone with more experience experience reading the c++
standard could take a look at this and confirm whether this is a libc++ bug, or
an lldb bug.

You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20190905/f3fe9cb2/attachment-0001.html>

More information about the llvm-bugs mailing list