SIGSEGV в DSO, смешанный C / C ++

Я использую интерфейс внешнего языка SWI-Prolog для C ++, пытаясь интегрировать другой ресурс.

В основном это работает, но любая попытка выбросить исключение приводит к SIGSEGV. Исключения обычно используются для проверки пользовательских параметров и, таким образом, являются фундаментальной частью интерфейса.

Я компилирую SWI-Prolog из исходного кода (через поставляемый скрипт), а флаги CXX

-c -O2 -gdwarf-2 -g3 -Wall -pthread -fPIC 

Я использую те же флаги для компиляции кода на C ++, который собран в .so, динамически загружен в SWI-Prolog (через dlopen, я думаю).

Проверка стека (через GDB) после SEGV показывает IP при , внутри __cxa_allocate_exception. Вероятно, __cxa_get_globals @ plt недоступен.

  Dump of assembler code for function __cxa_allocate_exception: 0x00007ffff1d80220 : push %r12 0x00007ffff1d80222 : lea 0x80(%rdi),%r12 0x00007ffff1d80229 : push %rbp 0x00007ffff1d8022a : mov %r12,%rdi 0x00007ffff1d8022d : push %rbx 0x00007ffff1d8022e : callq 0x7ffff1d1de30  0x00007ffff1d80233 : test %rax,%rax 0x00007ffff1d80236 : mov %rax,%rbx 0x00007ffff1d80239 : je 0x7ffff1d802d8  0x00007ffff1d8023f : callq 0x7ffff1d1efc0  0x00007ffff1d80244 : addl $0x1,0x8(%rax) 0x00007ffff1d80248 : test $0x1,%bl 0x00007ffff1d8024b : mov %rbx,%rdi 0x00007ffff1d8024e : mov $0x80,%edx 0x00007ffff1d80253 : jne 0x7ffff1d803d0  0x00007ffff1d80259 : test $0x2,%dil 

Единственный ресурс, который мне удалось найти, кажется уместным

исключение требует поиска типаinfo

и это может иметь смысл SIGSEGV.

Но я не могу двигаться дальше. Конечно, я надеюсь на какой-то волшебный флаг CXX или LD. Или я должен украсить пункты входа в библиотеку (я знаком с Windows declspec (s), я использовал их для создания библиотек DLL MFC) или что-то еще?

При вызове из Prolog вы не можете исключать какие-либо исключения в kernel ​​Prolog. Интерфейс C ++ поймает PlException и его подclassы и преобразует их в исключения Prolog. Не допускается исключение всех других исключений из вашей библиотеки.

Поскольку SWI Prolog является LGPL, вы, вероятно, динамически связываетесь с ним. Поэтому вы должны убедиться, что все C ++, которые были выбраны, имеют видимость по умолчанию в ELF-системах.