Исключения в Linux из общего объекта (.so)
У меня есть тестовая программа под названием ftest. Он загружает.so файлы, которые содержат тесты, и запускает найденные там тесты. Один из этих тестов загружает и запускает.so, который содержит драйвер базы данных Postgres для нашего O/RM.
Когда драйвер Postgres генерирует исключение, которое определено в этом файле.so (или том, на которое он ссылается, но ftest не ссылается на него) и перехватывается тестовой средой, деструктор исключения вызывает ошибку сегмента.
Этот segfault происходит всякий раз, когда скомпилированное исключение находится в.so, который был динамически загружен (используя dload).
Подобные вещи прекрасно работают в Windows, которая имеет такую же архитектуру. На самом деле мы не хотим ограничивать себя использованием только исключений из базовых библиотек - надстройки должны иметь возможность создавать свои собственные классы исключений и обрабатывать их как обычно.
Исключениями являются подклассы std::exception. Иногда исключения могут быть определены в библиотеках (таких как libpqxx), что означает, что исключения также иногда находятся вне нашего контроля.
Исключения создаются с использованием чего-то вроде:
throw exception_class( exception_arguments );
И ловятся с помощью:
catch ( std::exception &e ) {
// handler code
}
Есть ли какая-то специальная опция компилятора, необходимая, чтобы это работало? Нужно ли нам переключаться, чтобы генерировать исключения через throw new exception_class( args )
(мы не хотим этого делать)?
1 ответ
Предполагая, что вы используете gcc -
Добавьте -Wl,-E при сборке исполняемого файла, вызывающего dlload(). Это экспортирует все символы типа информации из исполняемого файла, что должно позволить RTTI (при перехвате исключения) работать должным образом.
VC++ использует сравнения строк для соответствия typeinfo, что приводит к более медленной динамической трансляции<> и т. Д., Но меньшим двоичным файлам. g++ использует сравнения указателей.
Я столкнулся с той же проблемой, когда пытался использовать классы чисто виртуальных интерфейсов, реализованные во время загрузки.so.
В сети также есть несколько статей, касающихся этой темы.
надеюсь, это поможет, Хейман.