Исключения в Linux из общего объекта (.so) - PullRequest
4 голосов
/ 17 июня 2009

У меня есть тестовая программа под названием 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 Ответ

6 голосов
/ 17 июня 2009

Если вы используете gcc -

Добавить -Wl, -E при сборке исполняемого файла, вызывающего dlload (). Это экспортирует все информационные символы типа из исполняемого файла, что должно позволить RTTI (при перехвате исключения) работать должным образом.

VC ++ использует сравнения строк для соответствия typeinfo, что приводит к более медленной динамической трансляции <> и т. Д., Но меньшим двоичным файлам. g ++ использует сравнения указателей.

Я столкнулся с той же проблемой при попытке использовать классы чисто виртуальных интерфейсов, реализованные в загруженной среде выполнения .so.

В сети есть несколько статей, касающихся этой темы.

надеюсь, что это поможет, Хейман.

...