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

发布于 2025-01-05 17:59:38 字数 2006 浏览 0 评论 0原文

我正在使用 C++ 的 SWI-Prolog 外语界面,尝试整合一些其他资源。

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

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

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

我使用相同的标志来编译我的 C++ 代码,该代码在 .so 中组装,在 SWI-Prolog 中动态加载(通过 dlopen , 我认为)。

SEGV 之后对堆栈的检查(通过 GDB)显示 IP 位于 __cxa_allocate_exception 内的 <+36> 处。可能 __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)或其他什么?

I'm using the SWI-Prolog foreign language interface for C++, attempting to integrate some other resource.

It mostly works, but any attempt to throw an exception result in a SIGSEGV. Exceptions are routinely used in validation of user parameters, and thus are a fundamental part of the interface.

I'm compiling SWI-Prolog from source (via supplied script), and the CXX flags are

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

I'm using the same flags to compile my C++ code, that is assembled in a .so, dynamically loaded in SWI-Prolog (via dlopen, I think).

Inspection of the stack (via GDB) after the SEGV shows the IP at <+36>, inside __cxa_allocate_exception. Likely __cxa_get_globals@plt isn't accessible.

        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

The only resource I've been able to find that seems pertinent claims

the exception requires a typeinfo lookup

and this could make sense of the SIGSEGV.

But I'm unable to proceed now. Of course, I hope in some magic CXX or LD flag.
Or should I decorate my library entry points (I'm acquainted to Windows declspec(s), I used them extensively to build MFC extension DLLs) or whatever?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

土豪我们做朋友吧 2025-01-12 17:59:38

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

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

When called from Prolog, you can't throw any exceptions into the Prolog kernel. The C++ interface will catch PlException and its subclasses and transform them into Prolog exceptions. All other exceptions must not be allowed to escape your library.

Since SWI Prolog is LGPL, you are probably dynamically linking to it. Therefore, you must ensure that all C++ that are thrown have default visibility on ELF systems.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文