I'm testing a C++ library under Cygwin in a debug configuration. The debug configuration includes the following CXXFLAGS
:
-DDEBUG -g3 -O2 -D_GLIBCXX_DEBUG -std=c++03
The test is dying at:
Testing PolynomialMod2 bit operations...
Program received signal SIGABRT, Aborted.
0x00000003fc705155 in cygstdc++-6!_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE8overflowEi () from /usr/bin/cygstdc++-6.dll
(gdb) shell echo ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE8overflowEi | c++filt
std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::overflow(int)
(gdb) where
#0 0x00000003fc705155 in cygstdc++-6!_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE8overflowEi () from /usr/bin/cygstdc++-6.dll
#1 0x0000000000000000 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
From the GDB session, the crash is in std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::overflow(int)
.
The code in question uses a ostringstream
, but I can't duplicate the problem with a simple test case. Unusually this points to a memory error and "try harder" answer, but I'm not sure in this case. In this case, the code is well tested and clean under:
- Elevated compiler warnings
- Clang and GCC sanitizers
- Valgrind
- Coverity analysis
- OS X Scribble Guards
- Microsoft Enterprise Analysis
If I remove _GLIBCXX_DEBUG
, then the issue goes away.
I'm thinking there may be a binary or object incompatibility when using _GLIBCXX_DEBUG
, and that's causing the crash. I experienced a similar crash years ago using Boost on Ubuntu with _GLIBCXX_DEBUG
, and the work around was to stop using Boost with _GLIBCXX_DEBUG
.
My first question is, are there incompatibilities between programs built with (and without) _GLIBCXX_DEBUG
and cygstdc++-6.dll
?
My second question is, if there is a compatibility issue, is there a debug version of cygstdc++-6.dll
that I can link against?
UPDATE: from matzeri's comment:
Cygwin is not using GLIBC but NEWLIB a C library
However, the tools are telling me they are using GNU's libstdc++
:
$ echo $CXXFLAGS
-DDEBUG -g3 -O2
$ g++ $CXXFLAGS -x c++ adhoc.cpp.proto -dM -E - < /dev/null | grep __GLIBCXX__
#define __GLIBCXX__ 20151204
adhoc.cpp.proto
is effectively an empty main. It includes an STL header to ensure the proper defines are present (the GCC folks told me I had to include the header).
Here's the actual test where the makefile adds the define: Makefile | GLIBCXX test:
325 # Debug testing on GNU systems. Triggered by -DDEBUG.
326 ifneq ($(filter -DDEBUG -DDEBUG=1,$(CXXFLAGS)),)
327 USING_GLIBCXX := $(shell $(CXX) -x c++ $(CXXFLAGS) -E adhoc.cpp.proto 2>&1 | $(EGREP) -i -c "__GLIBCXX__")
328 ifneq ($(USING_GLIBCXX),0)
329 ifeq ($(findstring -D_GLIBCXX_DEBUG,$(CXXFLAGS)),)
330 CXXFLAGS += -D_GLIBCXX_DEBUG
331 endif # CXXFLAGS
332 endif # USING_GLIBCXX
333 endif # GNU Debug build
Here's the simple test program I've been trying to duplicate it with. Its include for completeness, but it does not tickle the problem:
$ cat test.cxx
#include <sstream>
#include <iostream>
#include <string>
#include <algorithm>
int main(int argc, char* argv[])
{
std::ostringstream oss;
oss << argc;
oss << std::endl;
oss << ",";
oss << std::endl;
oss << "abcdefghijklmnopqrstuvwxyz";
oss << std::endl;
std::string str = oss.str();
str.erase(std::remove(str.begin(), str.end(), ','), str.end());
str.erase(str.end() - 1);
std::cout << str << std::endl;
return argc;
}