#c #multithreading #clang #mutex #static-analysis
Вопрос:
После попытки внедрить необходимые аннотации в существующую кодовую базу я не смог удалить, казалось бы, простое предупреждение. Я привел самый простой пример, и все равно никакой радости.
Я вырезал и вставил mutex.h
заголовок точно так, как указано в Анализе безопасности потоков. Похоже, я не могу выполнить блокировку области действия без предупреждения. Вот код:
#include "mutex.h"
#include <iostream>
// functions added just to complete the implementation
void Mutex::Lock()
{
}
void Mutex::GenericUnlock()
{
}
// test a scoped lock
void do_something(Mutex amp;m)
{
auto locker = MutexLocker(amp;m);
std::cout << "Hello, world!n";
}
int main(int argc, char** argv)
{
Mutex my_mutex;
do_something(my_mutex);
}
Компиляция с clang -o thread_static_analysis thread_static_analysis.cpp -std=c 17 -Wthread-safety
выдает следующее предупреждение:
thread_static_analysis.cpp:18:1: warning: releasing mutex 'locker' that was not held [-Wthread-safety-analysis]
}
^
1 warning generated.
Либо (1) я что-то упускаю, либо (2) это ложноположительный результат, который следует игнорировать до тех пор, пока проблема с реализацией clang не будет решена. Поиск таких проблем пока не дал никаких полезных результатов.
clang version 10.0.0-4ubuntu1
Target: x86_64-pc-linux-gnu
Thread model: posix
Ответ №1:
Насколько я понимаю, вы потенциально создаете копию временного MutexLocker
объекта в
auto locker = MutexLocker(amp;m);
(или анализ безопасности потоков думает, что вы его создаете). Затем временное устройство уничтожается и вызывает m.Unlock()
. Затем в конце функции locker
объект уничтожается и вызывается m.Unlock()
снова (что приводит к ошибке двойного выпуска).
Комментарии:
1. Спасибо. Я только что проделал некоторую работу с операциями перемещения, и, очевидно, это застряло у меня в голове. В то время как компилятор должен сделать это назначением перемещения, с точки зрения статического анализа это назначение копирования, следовательно, временные. Я сменил его на
MutexLocker locker(m);
, и все хорошо.2. @JohnJones на самом деле больше всего (всех?) компиляторы в любом случае избавились бы от временного (даже в режиме C 98), но TSA относится к конструкции консервативно.