[PATCH 2/2, applied] suppression: Fix race conditions
Dodji Seketeli
dodji@seketeli.org
Thu Sep 10 14:42:08 GMT 2026
Hello,
Accessing data members of the suppression specification types is not
necessarily thread-safe. This patch is an attempt to fix that.
Running the tests with thread-sanitizer enabled on Fedora Rawhide
seems to pass now.
* src/abg-suppression-priv.h (suppression_base::priv::mutex_):
Make this mutable.
(suppression_base::priv::{get_file_name_regex,
get_file_name_not_regex, get_soname_regex, get_soname_not_regex}):
Synchronize against mutex_.
(function_suppression::parameter_spec::priv::mutex_): Add new data
member.
(function_suppression::parameter_spec::priv::{get_type_name_regex}):
Synchronize against mutex_.
(function_suppression::priv::mutex_): Make this a mutex, not a
recursive_mutex.
(function_suppression::priv::{get_name_regex, get_name_not_regex,
get_return_type_regex, get_symbol_name_regex,
get_symbol_name_not_regex, get_symbol_version_regex}): Synchronize
against mutex_.
(variable_suppression::priv::mutex_): Add a new data member.
(variable_suppression::priv::{get_name_regex, get_name_not_regex,
get_symbol_name_regex, get_symbol_name_not_regex,
get_symbol_version_regex, get_type_name_regex}): Synchronize
against mutex_.
Signed-off-by: Dodji Seketeli <dodji@seketeli.org>
---
src/abg-suppression-priv.h | 25 ++++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/src/abg-suppression-priv.h b/src/abg-suppression-priv.h
index ce5d1d2e..6e103ec6 100644
--- a/src/abg-suppression-priv.h
+++ b/src/abg-suppression-priv.h
@@ -36,7 +36,7 @@ using std::atomic;
/// The private data of @ref suppression_base.
class suppression_base::priv
{
- mutex mutex_;
+ mutable mutex mutex_;
std::atomic<bool> is_artificial_;
std::atomic<bool> drops_artifact_;
string label_;
@@ -84,6 +84,7 @@ public:
const regex::regex_t_sptr&
get_file_name_regex() const
{
+ lock_guard<mutex> lock(mutex_);
if (!file_name_regex_ && !file_name_regex_str_.empty())
file_name_regex_ = regex::compile(file_name_regex_str_);
return file_name_regex_;
@@ -100,6 +101,7 @@ public:
const regex::regex_t_sptr&
get_file_name_not_regex() const
{
+ lock_guard<mutex> lock(mutex_);
if (!file_name_not_regex_ && !file_name_not_regex_str_.empty())
file_name_not_regex_ = regex::compile(file_name_not_regex_str_);
return file_name_not_regex_;
@@ -116,6 +118,7 @@ public:
const regex::regex_t_sptr&
get_soname_regex() const
{
+ lock_guard<mutex> lock(mutex_);
if (!soname_regex_ && !soname_regex_str_.empty())
soname_regex_ = regex::compile(soname_regex_str_);
return soname_regex_;
@@ -132,6 +135,7 @@ public:
const regex::regex_t_sptr&
get_soname_not_regex() const
{
+ lock_guard<mutex> lock(mutex_);
if (!soname_not_regex_ && !soname_not_regex_str_.empty())
soname_not_regex_ = regex::compile(soname_not_regex_str_);
return soname_not_regex_;
@@ -216,6 +220,7 @@ class function_suppression::parameter_spec::priv
friend class function_suppression::parameter_spec;
friend class function_suppression;
+ mutable mutex mutex_;
size_t index_;
string type_name_;
string type_name_regex_str_;
@@ -236,6 +241,7 @@ class function_suppression::parameter_spec::priv
const regex::regex_t_sptr
get_type_name_regex() const
{
+ lock_guard<mutex> lock(mutex_);
if (!type_name_regex_ && !type_name_regex_str_.empty())
type_name_regex_ = regex::compile(type_name_regex_str_);
return type_name_regex_;
@@ -249,7 +255,7 @@ struct function_suppression::priv
{
friend class function_suppression;
- std::recursive_mutex mutex_;
+ mutable std::mutex mutex_;
change_kind change_kind_;
string name_;
string name_regex_str_;
@@ -310,6 +316,7 @@ struct function_suppression::priv
const regex::regex_t_sptr
get_name_regex() const
{
+ lock_guard<mutex> lock(mutex_);
if (!name_regex_ && !name_regex_str_.empty())
name_regex_ = regex::compile(name_regex_str_);
return name_regex_;
@@ -327,6 +334,7 @@ struct function_suppression::priv
const regex::regex_t_sptr
get_name_not_regex() const
{
+ lock_guard<mutex> lock(mutex_);
if (!name_not_regex_ && !name_not_regex_str_.empty())
name_not_regex_ = regex::compile(name_not_regex_str_);
return name_not_regex_;
@@ -344,6 +352,7 @@ struct function_suppression::priv
const regex::regex_t_sptr
get_return_type_regex() const
{
+ lock_guard<mutex> lock(mutex_);
if (!return_type_regex_ && !return_type_regex_str_.empty())
return_type_regex_ = regex::compile(return_type_regex_str_);
return return_type_regex_;
@@ -361,6 +370,7 @@ struct function_suppression::priv
const regex::regex_t_sptr
get_symbol_name_regex() const
{
+ lock_guard<mutex> lock(mutex_);
if (!symbol_name_regex_ && !symbol_name_regex_str_.empty())
symbol_name_regex_ = regex::compile(symbol_name_regex_str_);
return symbol_name_regex_;
@@ -378,6 +388,7 @@ struct function_suppression::priv
const regex::regex_t_sptr
get_symbol_name_not_regex() const
{
+ lock_guard<mutex> lock(mutex_);
if (!symbol_name_not_regex_ && !symbol_name_not_regex_str_.empty())
symbol_name_not_regex_ = regex::compile(symbol_name_not_regex_str_);
return symbol_name_not_regex_;
@@ -395,6 +406,7 @@ struct function_suppression::priv
const regex::regex_t_sptr
get_symbol_version_regex() const
{
+ lock_guard<mutex> lock(mutex_);
if (!symbol_version_regex_ && !symbol_version_regex_str_.empty())
symbol_version_regex_ = regex::compile(symbol_version_regex_str_);
return symbol_version_regex_;
@@ -424,6 +436,7 @@ struct variable_suppression::priv
{
friend class variable_suppression;
+ mutable mutex mutex_;
change_kind change_kind_;
string name_;
string name_regex_str_;
@@ -473,6 +486,7 @@ struct variable_suppression::priv
const regex::regex_t_sptr
get_name_regex() const
{
+ lock_guard<mutex> lock(mutex_);
if (!name_regex_ && !name_regex_str_.empty())
name_regex_ = regex::compile(name_regex_str_);
return name_regex_;
@@ -490,6 +504,7 @@ struct variable_suppression::priv
const regex::regex_t_sptr
get_name_not_regex() const
{
+ lock_guard<mutex> lock(mutex_);
if (!name_not_regex_ && !name_not_regex_str_.empty())
name_not_regex_ = regex::compile(name_not_regex_str_);
return name_not_regex_;
@@ -507,6 +522,7 @@ struct variable_suppression::priv
const regex::regex_t_sptr
get_symbol_name_regex() const
{
+ lock_guard<mutex> lock(mutex_);
if (!symbol_name_regex_ && !symbol_name_regex_str_.empty())
symbol_name_regex_ = regex::compile(symbol_name_regex_str_);
return symbol_name_regex_;
@@ -524,6 +540,7 @@ struct variable_suppression::priv
const regex::regex_t_sptr
get_symbol_name_not_regex() const
{
+ lock_guard<mutex> lock(mutex_);
if (!symbol_name_not_regex_ && !symbol_name_not_regex_str_.empty())
symbol_name_not_regex_ = regex::compile(symbol_name_not_regex_str_);
return symbol_name_not_regex_;
@@ -539,8 +556,9 @@ struct variable_suppression::priv
/// @return a pointer to the regular expression object of
/// variable_suppression::priv::symbol_version_regex_str_.
const regex::regex_t_sptr
- get_symbol_version_regex() const
+ get_symbol_version_regex() const
{
+ lock_guard<mutex> lock(mutex_);
if (!symbol_version_regex_ && !symbol_version_regex_str_.empty())
symbol_version_regex_ = regex::compile(symbol_version_regex_str_);
return symbol_version_regex_;
@@ -558,6 +576,7 @@ struct variable_suppression::priv
const regex::regex_t_sptr
get_type_name_regex() const
{
+ lock_guard<mutex> lock(mutex_);
if (!type_name_regex_ && !type_name_regex_str_.empty())
type_name_regex_ = regex::compile(type_name_regex_str_);
return type_name_regex_;
--
2.55.0
--
Dodji
More information about the Libabigail
mailing list