问题
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?
回答1:
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.
来源:https://stackoverflow.com/questions/9290625/sigsegv-in-dso-mixed-c-c