-
Notifications
You must be signed in to change notification settings - Fork 211
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
Test hangs with TSAN #5117
Labels
Comments
This was referenced Mar 16, 2023
Merged
As far as I found, google/sanitizers#498 is the most closest problem in terms of that pthread_cond_wait is releated. But it's very old so I am not sure it's the same problem |
It reproduces with a small c++ code outside CCF takurosato@takurosato-virtual2:~/misc/tsan$ cat main.cpp
#include <iostream>
#include <thread>
#include <algorithm>
#include <vector>
#include <mutex>
#include <memory>
#include <atomic>
#include <condition_variable>
namespace threading
{
using ThreadID = uint16_t;
static constexpr ThreadID MAIN_THREAD_ID = 0;
static std::atomic<ThreadID> next_thread_id = MAIN_THREAD_ID;
uint16_t get_current_thread_id()
{
thread_local ThreadID this_thread_id = next_thread_id.fetch_add(1);
return this_thread_id;
}
void reset_thread_id_generator()
{
next_thread_id.store(MAIN_THREAD_ID);
}
}
int main() {
std::mutex assigned_ids_lock;
std::vector<uint16_t> assigned_ids;
const auto main_thread_id = threading::get_current_thread_id();
// REQUIRE(main_thread_id == threading::MAIN_THREAD_ID);
assigned_ids.push_back(main_thread_id);
std::mutex all_done_lock;
std::condition_variable all_done;
auto fn = [&]() {
{
std::lock_guard<std::mutex> guard(assigned_ids_lock);
const auto current_thread_id = threading::get_current_thread_id();
assigned_ids.push_back(current_thread_id);
}
{
std::unique_lock lock(all_done_lock);
all_done.wait(lock);
}
};
constexpr size_t num_threads = 20;
constexpr size_t expected_ids = num_threads + 1; // Includes MAIN_THREAD_ID
std::vector<std::thread> threads;
for (auto i = 0; i < num_threads; ++i)
{
threads.emplace_back(fn);
}
size_t attempts = 0;
constexpr size_t max_attempts = 5;
while (true)
{
{
std::lock_guard<std::mutex> guard(assigned_ids_lock);
if (assigned_ids.size() == expected_ids)
{
all_done.notify_all();
break;
}
}
// REQUIRE(++attempts < max_attempts);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
// REQUIRE(assigned_ids.size() == expected_ids);
for (auto& thread : threads)
{
thread.join();
}
const auto unique = std::unique(assigned_ids.begin(), assigned_ids.end());
// REQUIRE_MESSAGE(
// unique == assigned_ids.end(),
// fmt::format(
// "Thread IDs are not unique: {}", fmt::join(assigned_ids, ", ")));
}
takurosato@takurosato-virtual2:~/misc/tsan$ cat run.sh
#!/bin/bash
clang++-15 -g -pthread -stdlib=libc++ -fsanitize=thread -std=c++20 main.cpp && ./a.out |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
part of #4994
It happens in
Virtual MultiThreadTsan
CIhttps://dev.azure.com/MSRC-CCF/CCF/_build/results?buildId=67000&view=logs&j=7944d106-e7da-5d45-12ec-6dfc8e3f5a03&t=564afb6e-c35d-5add-8e9b-52387eab437a
Reproduce
Also you can reproduce it locally.
Note that the tests you see this bug are different depending of clang version.
If you use clang-12, you don't see this in
ds_test
, but still do ine2e_logging_cft
etc.In which test cases does it happen?
ds_test and many E2E tests.
Smallest test to reproduce it.
ds_test is the handy one to reproduce.
Looks like it happens in "Unique thread IDs" test case in thread_messaging.cpp. The ds_test passes without it.
In other terminal,
The text was updated successfully, but these errors were encountered: