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-адрес по адресу ‹+36> внутри __cxa_allocate_exception. Вероятно, __cxa_get_globals@plt недоступен.

        Dump of assembler code for function __cxa_allocate_exception:
0x00007ffff1d80220  <+0>:               push   %r12
0x00007ffff1d80222  <+2>:               lea    0x80(%rdi),%r12
0x00007ffff1d80229  <+9>:               push   %rbp
0x00007ffff1d8022a  <+10>:              mov    %r12,%rdi
0x00007ffff1d8022d  <+13>:              push   %rbx
0x00007ffff1d8022e  <+14>:              callq  0x7ffff1d1de30 <malloc@plt>
0x00007ffff1d80233  <+19>:              test   %rax,%rax
0x00007ffff1d80236  <+22>:              mov    %rax,%rbx
0x00007ffff1d80239  <+25>:              je     0x7ffff1d802d8 <__cxa_allocate_exception+184>
0x00007ffff1d8023f  <+31>:              callq  0x7ffff1d1efc0 <__cxa_get_globals@plt>
0x00007ffff1d80244  <+36>:              addl   $0x1,0x8(%rax)
0x00007ffff1d80248  <+40>:              test   $0x1,%bl
0x00007ffff1d8024b  <+43>:              mov    %rbx,%rdi
0x00007ffff1d8024e  <+46>:              mov    $0x80,%edx
0x00007ffff1d80253  <+51>:              jne    0x7ffff1d803d0 <__cxa_allocate_exception+432>
0x00007ffff1d80259  <+57>:              test   $0x2,%dil

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

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

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

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


person CapelliC    schedule 15.02.2012    source источник
comment
Я не могу вам помочь, но если вы не получили ответы здесь, попробуйте список рассылки SWI-Prolog — Ян очень полезен и внимателен к этому списку: swi-prolog.org/Mailinglist.html   -  person    schedule 29.02.2012
comment
@sharky: я уже писал там (15 февраля, исключения в C++ FLI), но никакой подсказки не пришло. Я также разместил минимальный тестовый пример (2 файла буквально из 2 строк), чтобы воспроизвести ошибку, но я не знаю, проверял ли это кто-то еще...   -  person CapelliC    schedule 29.02.2012


Ответы (1)


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

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

person Demi    schedule 29.10.2015