| Summary: | DRD does not detect thread hazards with C++ lambdas that capture by reference | ||
|---|---|---|---|
| Product: | [Developer tools] valgrind | Reporter: | Paul Floyd <pjfloyd> |
| Component: | drd | Assignee: | Paul Floyd <pjfloyd> |
| Status: | REPORTED --- | ||
| Severity: | normal | ||
| Priority: | NOR | ||
| Version First Reported In: | 3.24 GIT | ||
| Target Milestone: | --- | ||
| Platform: | Other | ||
| OS: | Linux | ||
| Latest Commit: | Version Fixed/Implemented In: | ||
| Sentry Crash Report: | |||
I've been debugging drd_trace_store_1 and drd_trace_load_1
For the load
if (DRD_(running_thread_is_recording_loads)()
&& (s_check_stack_accesses
|| ! DRD_(thread_address_on_stack)(addr))
&& bm_access_load_1_triggers_conflict(addr)
&& ! DRD_(is_suppressed)(addr, addr + 1))
{
drd_report_race(addr, 1, eLoad);
}
DRD_(thread_address_on_stack)(addr) is false (the address is above the call frame of the lambda in the call frame of main).
I need to debug the bitmaps related to this address to see why no conflict is detected.
I also tried this with some heap memory and still no error detected. |
This example #include <future> #include <iostream> int main() { char counter = 0; auto future1 = std::async(std::launch::async, [&]() { counter++; }); auto future2 = std::async(std::launch::async, [&]() { return counter; }); future1.wait(); // Cast to int to print it as a numerical value rather than a character std::cout << (int)future2.get(); } from https://github.com/knatten/cpp-brain-teasers.git generates errors with both Helgrind and Thread Sanitizer on Linux with g++ and libstdc++. Nothing with Helgrind on FreeBSD with clang++/libc++. No error with DRD. /home/paulf/tools/valgrind/bin/valgrind --tool=drd --check-stack-var=yes -q ./back-from-the-future 1 I think that this is because the memory for the captured reference to counter is neither on the stack of the lambda nor on the heap.