Совместимость ABI между выпуском и отладкой
При использовании GCC, учитывая, что я компилирую одну и ту же библиотеку иногда в выпуске, а иногда в отладке, гарантируется ли совместимость ABI?
(используя тот же компилятор)
У меня есть исполняемый файл и некоторые общие объекты (некоторые зависят от других), я хочу иметь возможность менять / освобождать общие объекты без перекомпиляции всего, кроме только общих общих объектов.
Возможно ли это, или есть какой-то сценарий, где я мог бы получить неопределенное поведение таким образом? (Предполагая, что мой код строго упакован и дополнен как релизом, так и отладкой)
РЕДАКТИРОВАТЬ:
Я подробно остановлюсь на проблеме, которую мы видим. У нас есть пользовательская версия intrusive_ptr
в режиме отладки у нас есть свой intrusive_ptr
который имеет один член, который является boost::intrusive_ptr
, а в релизе мы просто используем boost::intrusive_ptr
, API нашего intrusive_ptr
это то же самое из boost::intrusive_ptr
и у нас нет никаких виртуальных функций в классе.
То, что мы видим, это:
Если мы используем все библиотеки отладки или все библиотеки выпуска, все работает хорошо. Если мы смешиваем исполняемый файл отладки с релизными библиотеками, происходит утечка памяти из intrusive_ptr
и это не освобождает объект.
Размер нашего intrusive_ptr
а также boost::intrusive_ptr
идентичны как в отладке, так и в выпуске (наш класс не добавляет никаких дополнительных размеров).
Поэтому мне интересно, что может быть причиной утечки, единственное, что приходит на ум, - это различие ABI.
Идеи?
2 ответа
Я знал несколько компиляторов, которые генерируют несовместимый код для выпуска и отладки (хотя эти компиляторы давно устарели). На самом деле я бы не стал доверять объектным модулям полностью совместимым, если они не были скомпилированы с точно такими же флагами.
Вот почему make-файлы (следуя принципам GNU) и IDE, такие как Eclipse, собирают объекты release/debug/profile в разные каталоги. Чтобы убедиться, что они никогда не могут быть перепутаны.
Как правило, нет, потому что обычная разница между выпуском и отладочной сборкой - это просто варианты, позволяющие сделать шаг отладки лучше. Но неожиданное поведение все еще возможно, если вы по-разному определяете другие параметры (например, целочисленный размер, целевую архитектуру и т. Д.) Между сборками выпуска и отладки, параметры вызывающей стороны могут не соответствовать ожиданиям вызываемой стороны. Также могут быть проблемы с безопасностью исключений и константой, которую компоновщик времени выполнения может не проверять.