This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug libstdc++/17664] New: Crash in std::map when using _GLIBCXX_DEBUG with multithreading
- From: "lothar at xcerla dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 24 Sep 2004 22:05:54 -0000
- Subject: [Bug libstdc++/17664] New: Crash in std::map when using _GLIBCXX_DEBUG with multithreading
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
There is a (multithreaded) condition where the STL behaves different if
compiled with or without _GLIBCXX_DEBUG. If _GLIBCXX_DEBUG is defined the
attached program crashes. To compile the attached program the ACE
(http://www.cs.wustl.edu/~schmidt/ACE.html) library which can be downloaded at
http://deuce.doc.wustl.edu/Download.html is needed.
I suspect that the iterators make some modifications on the map they iterate
on if _GLIBCXX_DEBUG is defined. This leads to different (and in this case
erroneous) behavior in multithreaded applications.
Lothar
--------------------------------- cut ---------------------------------------
/*
# compile without _GLIBCXX_DEBUG
lothar@janus-w$ g++ -V 3.4.1 -O0 -g -I ${ACE_ROOT}/ -L ${ACE_ROOT}/lib/ -lACE
-lstdc++ -lpthread -lrt -ldl bug.cpp -o bug
lothar@janus-w$ LD_LIBRARY_PATH=${ACE_ROOT}/lib ./bug
lothar@janus-w$
# compile with _GLIBCXX_DEBUG but guard with a write lock
lothar@janus-w$ g++ -V 3.4.1 -O0 -g -D_GLIBCXX_DEBUG -I ${ACE_ROOT}/ -L
${ACE_ROOT}/lib/ -lACE -lstdc++ -lpthread -lrt -ldl bug.cpp -o bug
lothar@janus-w$ LD_LIBRARY_PATH=${ACE_ROOT}/lib ./bug
lothar@janus-w$
# compile with _GLIBCXX_DEBUG (crashes)
lothar@janus-w$ g++ -V 3.4.1 -O0 -g -D_GLIBCXX_DEBUG -DCRASH -I ${ACE_ROOT}/
-L ${ACE_ROOT}/lib/ -lACE -lstdc++ -lpthread -lrt -ldl bug.cpp -o bug
bug.cpp:19:2: warning: #warning will crash
lothar@janus-w$ LD_LIBRARY_PATH=${ACE_ROOT}/lib ./bug
Segmentation fault
lothar@janus-w$
*/
#include <algorithm>
#include <map>
#include "ace/Task.h"
#include "ace/Barrier.h"
#define PROTECT 1
#ifdef _GLIBCXX_DEBUG
#ifdef CRASH
#undef PROTECT
#define PROTECT 0
#warning will crash
#endif /* CRASH */
#endif /* _GLIBCXX_DEBUG */
class MapTask
:
public ACE_Task_Base
{
public:
MapTask(
unsigned long cnt,
unsigned long threadCnt
)
:
m_barrier(threadCnt+1),
m_id(0),
m_failed(0),
m_cnt(cnt),
m_threadCnt(threadCnt)
{
for(cnt = 0; cnt < m_cnt; ++cnt)
{
m_map[cnt] = 0;
}
this->activate(
THR_NEW_LWP|THR_JOINABLE|THR_INHERIT_SCHED,
m_threadCnt
);
}
~MapTask()
{
}
virtual int init (int argc, char *argv[])
{
m_barrier.wait();
return 0;
}
virtual int fini (void)
{
this->wait();
return 0;
}
unsigned failed ( )
{
return m_failed.value();
}
virtual int svc (void)
{
long id = m_id++;
m_barrier.wait();
try
{
for(int cnt = 0; cnt < m_cnt; ++cnt)
{
if(id % 2)
{
WriteGuard guard(m_mutex);
m_map[cnt] += 1;
}
std::map<int,int>::const_iterator iter = m_map.end();
{
ReadGuard guard(m_mutex);
iter = m_map.find(cnt);
}
if(iter == m_map.end())
{
++m_failed;
}
else
{
unsigned long value = 0;
do
{
value += iter->second;
{
// we have to guard the iterator movement
// in the debug builds due to _GLIBCXX_DEBUG
#if PROTECT
WriteGuard guard(m_mutex);
#endif /* PROTECT */
++iter;
}
}while(iter != m_map.end());
}
ACE_OS::sleep(ACE_Time_Value(0,10));
}
}
catch(...)
{
return -1;
}
return 0;
}
private:
typedef ACE_Read_Guard < ACE_RW_Thread_Mutex > ReadGuard;
typedef ACE_Write_Guard < ACE_RW_Thread_Mutex > WriteGuard;
ACE_Thread_Barrier m_barrier;
ACE_RW_Thread_Mutex m_mutex;
ACE_Atomic_Op <ACE_Thread_Mutex, unsigned long> m_id;
ACE_Atomic_Op <ACE_Thread_Mutex, unsigned long> m_failed;
std::map<int,int> m_map;
unsigned long m_cnt;
unsigned long m_threadCnt;
};
int main ()
{
unsigned int numThreads = 200;
unsigned int numIterations = 100;
// create threads
MapTask task(numIterations, numThreads);
ACE_OS::sleep(1);
// run threads
task.init(0, 0);
// wait for completion
task.fini();
return 0;
} /* end of main */
------------------------------------- cut -----------------------------------
--
Summary: Crash in std::map when using _GLIBCXX_DEBUG with
multithreading
Product: gcc
Version: 3.4.1
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: libstdc++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: lothar at xcerla dot com
CC: gcc-bugs at gcc dot gnu dot org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17664