DSO中的SIGSEGV,混合C/C++

SIGSEGV in DSO, mixed C/C++

本文关键字:C++ 混合 中的 SIGSEGV DSO      更新时间:2023-10-16

我正在使用C++的SWI-Prolog外语接口,试图集成一些其他资源。

它基本上是有效的,但任何抛出异常的尝试都会导致SIGSEGV。异常通常用于验证用户参数,因此是界面的基本部分。

我正在从源代码(通过提供的脚本)编译SWI-Prolog,CXX标志是

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

我使用相同的标志来编译我的C++代码,这些代码在.so中汇编,动态加载在SWI Prolog中(我想是通过dlopen)。

在SEGV之后对堆栈的检查(经由GDB)显示IP处于<36>,位于__cxa_sallocate_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

我能找到的唯一一个似乎相关的资源声称

该异常需要类型信息查找

这可以理解SIGSEGV。

但我现在无法继续。当然,我希望有一些神奇的CXX或LD标志。或者我应该装饰我的库入口点(我熟悉Windows declspec,我广泛使用它们来构建MFC扩展DLL)或其他什么?

从Prolog调用时,不能向Prolog内核抛出任何异常。C++接口将捕获PlException及其子类,并将它们转换为Prolog异常。不得允许所有其他例外情况逃离您的库。

由于SWI-Prolog是LGPL,您可能正在动态链接到它。因此,您必须确保所有抛出的C++在ELF系统上都具有默认可见性。