Reviewed By: da319 Differential Revision: D9042172 fbshipit-source-id: a7052e061master
parent
5b3bca5562
commit
bbd26769c9
@ -0,0 +1,20 @@
|
|||||||
|
# Copyright (c) 2018-present, Facebook, Inc.
|
||||||
|
#
|
||||||
|
# This source code is licensed under the MIT license found in the
|
||||||
|
# LICENSE file in the root directory of this source tree.
|
||||||
|
|
||||||
|
TESTS_DIR = ../../..
|
||||||
|
|
||||||
|
ANALYZER = checkers
|
||||||
|
# see explanations in cpp/errors/Makefile for the custom isystem
|
||||||
|
CLANG_OPTIONS = -x c++ -std=c++11 -nostdinc++ -isystem$(ROOT_DIR) -isystem$(CLANG_INCLUDES)/c++/v1/ -c
|
||||||
|
|
||||||
|
INFER_OPTIONS = --starvation-only --debug-exceptions --project-root $(TESTS_DIR)
|
||||||
|
|
||||||
|
INFERPRINT_OPTIONS = --issues-tests
|
||||||
|
|
||||||
|
SOURCES = $(wildcard *.cpp)
|
||||||
|
|
||||||
|
include $(TESTS_DIR)/clang.make
|
||||||
|
|
||||||
|
infer-out/report.json: $(MAKEFILE_LIST)
|
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018-present, Facebook, Inc.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
namespace basics {
|
||||||
|
|
||||||
|
class Basic {
|
||||||
|
public:
|
||||||
|
Basic() {}
|
||||||
|
|
||||||
|
void thread1() {
|
||||||
|
mutex_1.lock();
|
||||||
|
mutex_2.lock();
|
||||||
|
|
||||||
|
mutex_2.unlock();
|
||||||
|
mutex_1.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread2() {
|
||||||
|
mutex_2.lock();
|
||||||
|
mutex_1.lock();
|
||||||
|
|
||||||
|
mutex_1.unlock();
|
||||||
|
mutex_2.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::mutex mutex_1;
|
||||||
|
std::mutex mutex_2;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WithGuard {
|
||||||
|
public:
|
||||||
|
WithGuard() {}
|
||||||
|
|
||||||
|
void thread1() {
|
||||||
|
std::lock_guard<std::mutex> lock1(mutex_1);
|
||||||
|
std::lock_guard<std::mutex> lock2(mutex_2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread2() {
|
||||||
|
std::lock_guard<std::mutex> lock2(mutex_2);
|
||||||
|
std::lock_guard<std::mutex> lock1(mutex_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::mutex mutex_1;
|
||||||
|
std::mutex mutex_2;
|
||||||
|
};
|
||||||
|
|
||||||
|
class StdLock {
|
||||||
|
public:
|
||||||
|
StdLock() {}
|
||||||
|
|
||||||
|
// no reports, std::lock magically avoids deadlocks
|
||||||
|
void thread1() {
|
||||||
|
std::lock<std::mutex>(mutex_1, mutex_2);
|
||||||
|
mutex_1.unlock();
|
||||||
|
mutex_2.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void thread2() {
|
||||||
|
std::lock<std::mutex>(mutex_2, mutex_1);
|
||||||
|
mutex_2.unlock();
|
||||||
|
mutex_1.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::mutex mutex_1;
|
||||||
|
std::mutex mutex_2;
|
||||||
|
};
|
||||||
|
} // namespace basics
|
@ -0,0 +1,2 @@
|
|||||||
|
codetoanalyze/cpp/starvation/basics.cpp, basics::Basic_thread1, 17, DEADLOCK, no_bucket, ERROR, [[Trace 1] `basics::Basic_thread1`,locks `this.mutex_1` in class `basics::Basic*`,locks `this.mutex_2` in class `basics::Basic*`,[Trace 2] `basics::Basic_thread2`,locks `this.mutex_2` in class `basics::Basic*`,locks `this.mutex_1` in class `basics::Basic*`]
|
||||||
|
codetoanalyze/cpp/starvation/basics.cpp, basics::WithGuard_thread1, 42, DEADLOCK, no_bucket, ERROR, [[Trace 1] `basics::WithGuard_thread1`,locks `this.mutex_1` in class `basics::WithGuard*`,locks `this.mutex_2` in class `basics::WithGuard*`,[Trace 2] `basics::WithGuard_thread2`,locks `this.mutex_2` in class `basics::WithGuard*`,locks `this.mutex_1` in class `basics::WithGuard*`]
|
Loading…
Reference in new issue