'Deadlock in __cxa_guard_acquire
First the code:
#pragma once
#include <type_traits>
// assign unique identifiers to types
template<typename ...>
class Family
{
static std::size_t identifier() noexcept
{
static std::size_t value = 0;
return value++;
}
template<typename ...>
static std::size_t family() noexcept
{
static const std::size_t value = identifier();
return value;
}
public:
using family_type = std::size_t;
template<typename ... Type>
static family_type type() noexcept
{
return family<std::decay_t<Type>...>();
}
};
// usage
using introspection_family = Family<struct IntrospectionRegistry>;
template<typename Structure>
void addIntrospectData(DataType introspection[MAX_TYPES], DataType const& dataType)
{
/* reserve index for this type in the introspection register */
const auto num = introspection_family::type<Structure>();
assert(num < MAX_TYPES);
introspection[num - 1] = dataType;
}
This code give an integer to each type and I use it in some kind of C++ introspection implementation.
The application isn't multi threaded.
When I compiled it in -O0, sometimes, the call to introspection_family::type<Structure>() blocks at __cxa_guard_acquire@plt and I get a deadlock.
When compiled with -O3, I don't have any problem, but that might just be because it becomes very difficult to reproduce.
__cxa_guard_acquire is used to ensure that the static variable is constructed before we access it but here it should be irrelevant as I'm not even in a threaded application.
Does anyone have any idea why this is happening ?
I use:
CXXFLAGS=-std=c++14 -O0 -g3 -pthread -Wall -Wextra -Werror
LDFLAGS= -g -pthread -lGLEW -lGLU -lGL -lSDL2_mixer -lSDL2
And I use gcc (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609
Solution 1:[1]
Adding the compile option -fno-threadsafe-statics helped. Since your application is single thread, this is OK.
I had a similar issue. However, the reason in my code was recursion. __cxa_guard_acquire will block when called recursively. A proper fix was needed. I did not check your code if this could also be your problem.
Additional info: The lock used might have a different name than __cxa_guard_acquire. It might also work with recursion, but this is compiler/libc++ specific and you should not rely on that.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
