This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[PATCH, libstdc++] Fix PR54172
- From: Thiago Macieira <thiago dot macieira at intel dot com>
- To: gcc-patches at gcc dot gnu dot org, libstdc++ at gcc dot gnu dot org
- Date: Thu, 30 Aug 2012 12:29:51 +0200
- Subject: [PATCH, libstdc++] Fix PR54172
Hello
The attached patch fixes a race condition in __cxa_guard_acquire, a regression
from 4.6. When the code was refactored to use the new atomic intrinsics, the
fact that __atomic_compare_exchange_n updates the "expected" variable with the
current value was missed.
That causes the loop to possibly overwrite a successful initialisation and re-
start the initialisation phase. The bug report has a gdb trace with a
watchpoint showing the guard variable transitioning
0 (uninit) -> 256 (pending) -> 1 (done) -> 256 (pending) -> 1 (done)
This situation can happen if both CAS fail in given thread: the first because
the other thread started the initialisation and the second because the
initialisation succeeded.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Intel Sweden AB - Registration Number: 556189-6027
Knarrarnäsgatan 15, 164 40 Kista, Stockholm, Sweden
2012-08-30 Thiago Macieira <thiago.macieira@intel.com>
PR libstdc++/54172
* libsupc++/guard.cc (__cxa_guard_acquire): Don't compare_exchange
from a finished state back to a waiting state.
---
libstdc++-v3/libsupc++/guard.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libstdc++-v3/libsupc++/guard.cc b/libstdc++-v3/libsupc++/guard.cc
index adc9608..4da9035 100644
--- a/libstdc++-v3/libsupc++/guard.cc
+++ b/libstdc++-v3/libsupc++/guard.cc
@@ -244,13 +244,13 @@ namespace __cxxabiv1
if (__gthread_active_p ())
{
int *gi = (int *) (void *) g;
- int expected(0);
const int guard_bit = _GLIBCXX_GUARD_BIT;
const int pending_bit = _GLIBCXX_GUARD_PENDING_BIT;
const int waiting_bit = _GLIBCXX_GUARD_WAITING_BIT;
while (1)
{
+ int expected(0);
if (__atomic_compare_exchange_n(gi, &expected, pending_bit, false,
__ATOMIC_ACQ_REL,
__ATOMIC_RELAXED))
--
1.7.11.4