STL и выпуск / отладка библиотеки беспорядок - PullRequest
9 голосов
/ 22 января 2011

Я пользуюсь какой-то третьей стороной. Я использую версию с общей библиотекой, так как она большая (~ 60 МБ) и используется несколькими приложениями.

Есть ли способ при запуске приложения узнать, что версия выпуска / отладки библиотеки используется соответственно для версии выпуска / отладки моего приложения?

Более подробное описание

Библиотека, которая предоставляет интерфейс C ++. Один из методов API возвращает std::vector<std::string>.

Проблема, когда я компилирую свое приложение в режиме отладки, следует использовать отладочную версию библиотеки. То же самое для выпуска. Если используется неверная версия библиотеки, приложение не работает.

По данным gcc (см. http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt03ch17s04.html)

но со стандартной библиотекой в ​​смешанном режиме который может использовать любой режим отладки или объекты basic_string в режиме выпуска, все усложняется

P.S. 1 * * тысяча двадцать-один

Похоже, что предложение Timbo является возможным решением - используйте разные soname для библиотек отладки и выпуска. Итак, что нужно передать скрипту ./configure для изменения библиотеки soname?

P.S. 2

Моя проблема не во время соединения, а во время выполнения.

P.S. 3

Здесь - вопрос, демонстрирующий проблему, с которой я сталкиваюсь.

Ответы [ 4 ]

7 голосов
/ 23 января 2011

Режим отладки, на который ссылается здесь , не имеет ничего общего с отладочной или выпускной сборкой вашего приложения. Режим отладки STL активируется с помощью -D_GLIBCXX_DEBUG и является специальным режимом проверки.

Маловероятно, что сторонняя библиотека была фактически скомпилирована с режимом проверки STL, но если бы это было так, она, скорее всего, очень быстро указала бы, что ваш код также должен быть скомпилирован с -D_GLIBCXX_DEBUG.

Если сторонняя библиотека не была собрана с проверкой STL, то она совместима с вашим кодом независимо от того, выполняете ли вы оптимизированную или отладочную сборку.

Поскольку вы утверждаете, что отладочная сборка вашего кода, связанная с оптимизированной сборкой сторонней библиотеки, вызывает сбой, этот сбой, скорее всего, вызван ошибкой в ​​вашем коде (или, возможно, ошибкой в ​​сторонней библиотеке).

Valgrind и GDB - ваши друзья.

5 голосов
/ 29 января 2011

Я полагаю, что вы неправильно прочитали документацию по указанной вами ссылке. В частности, вы неправильно поняли его назначение - этот раздел называется «Цели» и описывает ряд гипотетических проектов для библиотеки отладки C ++ и последствия этих проектов для объяснения фактического выбора дизайна, который был сделан. Куски текста, которые следуют за цитируемыми вами строками, описывают хаос, который мог возникнуть в результате гипотетической реализации, которая имела отдельные конструкции для строк режима выпуска и режима отладки. Далее говорится:

По этой причине мы не можем легко предоставить безопасные итераторы для шаблона класса std :: basic_string, так как он присутствует во всей стандартной библиотеке C ++.

(Или, перефразируя это, предоставить специальную «отладочную» версию итераторов строк невозможно.)

...

С дизайном режима отладки libstdc ++ мы не можем эффективно скрывать различия между строками режима отладки и выпуска от пользователя. Неспособность скрыть различия может привести к непредсказуемому поведению, и по этой причине мы решили выполнять только изменения basic_string, которые не требуют изменений ABI. Ожидается, что влияние на пользователей будет минимальным, так как существуют простые альтернативы (например, __gnu_debug :: basic_string), а преимущество в удобстве использования, которое мы получаем от возможности смешивать отлаженные и отладочные блоки перевода, огромно.

Другими словами, проектирование режимов отладки и выпуска в GCC libstdc ++ отклонило эту гипотетическую реализацию с отдельными проектами для строк, особенно для того, чтобы разрешить перекрестную связь типа, которого вы беспокоитесь о том, как избежать .

Таким образом, у вас не должно возникнуть проблем с компиляцией вашей библиотеки один раз, без -D_GLIBCXX_DEBUG (или с ней, если по какой-то причине вы предпочитаете), и связыванием ее с любым режимом вашего приложения. Если у вас есть проблемы, это связано с ошибкой где-то. [Но см. Правку ниже! Это относится только к std::string, а не к другим контейнерам!]

Редактировать: После того, как этот ответ был принят, я ответил на следующий вопрос на std :: vector crash и понял, что вывод этого ответа неверен. Libstdc ++ GCC делает умные вещи со строками для поддержки «перекомпиляции при использовании» (в которой все использования данного объекта-контейнера должны быть скомпилированы с одинаковыми флагами, но использование одного и того же класса контейнера в программе не обязательно должно быть скомпилировано с одним и тем же флагов), но это не то же самое, что полная «компиляция на единицу», которая обеспечит необходимую вам возможность сшивки. В частности, в документации говорится об этой способности сшивания,

Мы считаем, что этот уровень перекомпиляции на самом деле невозможен, если мы намереваемся предоставить безопасные итераторы, оставить семантику программы неизменной и не снижать производительность в режиме выпуска ....

Таким образом, если вы передаете контейнеры через интерфейс вашей библиотеки, вам понадобится две отдельные библиотеки. Честно говоря, для этой ситуации я обнаружил, что самое простое решение - просто установить две библиотеки в разные каталоги (по одной для каждого варианта - и вы захотите, чтобы обе они были отделены от каталога вашей основной библиотеки). Кроме того, вы можете переименовать файл библиотеки отладки, а затем установить его вручную.

Как еще одно предложение - вы, вероятно, не часто запускаете это в режиме отладки. Возможно, стоит статически скомпилировать и связать отладочную версию в свое приложение, поэтому вам не нужно беспокоиться об установке нескольких динамических библиотек и сохранении их прямо во время выполнения.

1 голос
/ 22 января 2011

Присвойте отладочной и выпускной версиям DLL разные имена и свяжите правильные с помощью библиотечной зависимости. Тогда ваше приложение не запустится, если не найдет правильную DLL.

0 голосов
/ 27 января 2011

Это такая проверка, которую вы должны выполнять в своей системе сборки. В вашем скрипте сборки

  • если вы создаете релиз, то создайте ссылку на библиотеку релизов.
  • если вы собираете для отладки, тогда ссылка на библиотеку отладки.

Например, если вы используете make:

release: $(OBJ)
    $(CC) $(CXXFLAGS_RELEASE) $(foreach LIB,$(LIBS_RELEASE),-l$(LIB))
debug: $(OBJ)
    $(CC) $(CXXFLAGS_DEBUG) $(foreach LIB,$(LIBS_DEBUG),-l$(LIB))
...