Рассмотрим следующую программу на C++ с ошибками:
Код: Выделить всё
#include
#include
#include
#include
#include
static std::mutex m;
static char *buf;
static void a()
{
for (;;) {
char *b;
{
std::lock_guard g{m};
b = buf;
}
if (b)
puts(b);
}
}
static void b()
{
for (;;) {
{
std::lock_guard g{m};
buf = strdup("foo");
}
{
std::lock_guard g{m};
buf = static_cast(realloc(buf, 10000));
strcpy(buf, "barbarbar");
}
{
std::lock_guard g{m};
free(buf);
buf = nullptr;
}
}
}
int main()
{
auto thread_a = std::thread(a);
auto thread_b = std::thread(b);
thread_a.join();
// unreachable
thread_b.join();
return 0;
}
При компиляции без специальных параметров и запуске с помощью valgrind ./a.out, на моем системе программа будет работать около 4 минут, прежде чем сообщит о первом недопустимом чтении размером 1. Я предполагаю, что это связано с тем, что Valgrind эмулирует несколько потоков путем упреждающего планирования в одном потоке, и поэтому вам понадобится некоторая удача, чтобы переключить контекст между a() и b() в нужный момент. для воспроизведения ошибки.
Аналогично, когда программа скомпилирована с помощью GCC или Clang с использованием -fsanitize=thread, кажется, что она продолжает работать без каких-либо проблем. p>
Мой вопрос: проводились ли какие-либо недавние научные исследования, которые могли бы улучшить алгоритм ThreadSanitizer в этом отношении?
Подробнее здесь: https://stackoverflow.com/questions/790 ... -same-time