Сбой в std:: basic_stringbuf<char...>:: переполнение
Я тестирую библиотеку C++ под Cygwin в конфигурации отладки. Конфигурация отладки включает в себя следующее CXXFLAGS
:
-DDEBUG -g3 -O2 -D_GLIBCXX_DEBUG -std=c++03
Тест умирает в:
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?)
От сеанса GDB сбой в std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::overflow(int)
,
В рассматриваемом коде используется ostringstream
, но я не могу продублировать проблему простым тестовым примером. Необычно, что это указывает на ошибку памяти и ответ "старайся усерднее", но я не уверен в этом. В этом случае код хорошо протестирован и очищен:
- Повышенные предупреждения компилятора
- Clang и GCC дезинфицирующие средства
- Valgrind
- Анализ покрытия
- OS X Scribble Guards
- Microsoft Enterprise Analysis
Если я удалю _GLIBCXX_DEBUG
, то проблема уходит.
Я думаю, что может быть двоичная или объектная несовместимость при использовании _GLIBCXX_DEBUG
и это вызывает аварию. Я столкнулся с подобным сбоем несколько лет назад, используя Boost на Ubuntu с _GLIBCXX_DEBUG
и обходной путь должен был прекратить использование Boost с _GLIBCXX_DEBUG
,
Мой первый вопрос: есть ли несовместимости между программами, созданными с (и без) _GLIBCXX_DEBUG
а также cygstdc++-6.dll
?
Мой второй вопрос: если есть проблема совместимости, есть ли отладочная версия cygstdc++-6.dll
что я могу связать против?
ОБНОВЛЕНИЕ: из комментария Мацери:
Cygwin не использует GLIBC, но NEWLIB библиотека C
Тем не менее, инструменты говорят мне, что они используют GNU 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
фактически пустая главная. Он включает в себя заголовок STL, чтобы обеспечить наличие соответствующих определений (ребята из GCC сказали мне, что я должен был включить заголовок).
Вот фактический тест, в котором make-файл добавляет определение: Makefile | GLIBCXX тест:
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
Вот простая тестовая программа, с которой я пытался ее дублировать. Это включает в себя для полноты, но это не щекочет проблему:
$ 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;
}