Sun Studio链接gcc libs:例外不工作 [英] Sun Studio linking gcc libs: exceptions do not work

查看:224
本文介绍了Sun Studio链接gcc libs:例外不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用Sun Studio构建应用程序。此应用程序使用一个共享库,只能使用Gnu C ++构建。共享库有一个C接口,所以代码可以由Sun编译器调用(这是为了避免名称调整问题,参见)。这个问题可以在下面的代码中找到。



除了异常处理之外的一切都很好。当在共享库中抛出异常时,程序会出现故障。这仅发生在使用Sun Studio编译器编译主程序时。



计划A:动态链接。使用Gnu C ++编译器编译下面的最小示例程序工作正常,共享库检测到异常。下面是设置示例:

  GCC SOLARIS STUDIO 
共享
c_layer.so< ---- application
(没有异常)(使用异常sol studio)
|
|使用标志-static -static-libstdc ++ -static-lib-gcc
v
gcc_only_lib.so
libstdc ++。所以
(使用gcc异常)

结果:抛出异常时出现分段违规(参见下面的代码)。



计划B:静态地链接



,但构建c_layer.a



结果:


未定义的第一个引用符号

在文件
__cxa_allocate_exception libs / cInterface / libcInterface.a c_layer.cpp.o)
std :: string ::〜std :: basic_string()
libs / cInterface / libcInterface.a(c_layer.cpp.o)
__cxa_end_catch libs / cInterface / libcInterface.a(c_layer.cpp.o)
__cxa_free_exception libs / cInterface / libcInterface.a(c_layer.cpp.o)
__cxa_begin_catch libs / cInterface / libcInterface.a $ b __cxa_throw libs / cInterface / libcInterface.a(c_layer.cpp.o)


问题为什么不使用Sun Studio进行exeption处理?






像这样:

  LD_PRELOAD = / usr / sfw / lib / amd64 / libgcc_s.so ./example 

它崩溃的方式不同:



$>





$ p $(dbx)其中
1 __lwp_sigqueue(0x1,0x6,0xffffc1000bae5060,
0xffffffff,0x0,0xffff80ffbffff810),0xffff80ffbf51e70a [2]
thr_kill(0x0,0x0,0x0,0x0,0x0,0x0),0xffff80ffbf512ec8 [3]
raise(0x0,0x0,0x0 ,0x0,0x0,0x0),在0xffff80ffbf4c291d [4]
中止(0x0,0x0,0x0,0x0,0x0,0x0),在0xffff80ffbf497ff2 [5]
__gnu_cxx :: __ verbose_terminate_handler(0x0,0x0,在0xffff80ffbd9dbd5b [7] std :: terminate(0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0),在0xffff80ffbd9de911 [6] __cxxabiv1 :: __ terminate(0x0,0x0,0x0,
0x0,
0x0,0x0,0x0,0x0),在0xffff80ffbd9dbda3 [8] __cxa_rethrow(0x0,
0x0,0x0,0x0,0x0,0x0),在0xffff80ffbd9dc02d [9]
__gnu_cxx :: __ verbose_terminate_handler (0x0,0x0,0x0,0x0,0x0,0x0),0xffff80ffbd9de8d4 [10] __cxxabiv1 :: __ terminate(0x0,0x0,0x0,
0x0,0x0,0x0),0xffff80ffbd9dbd5b [11] std :: terminate (0x0,0x0,
0x0,0x0,0x0,0x0),0xffff80ffbd9dbda3 [12] __cxa_throw(0x0,
0x0,0x0,0x0,0x0,0x0),0xffff80ffbd9dbfd6 [13] clayerCall ,
0x0,0x0,0x0,0x0,0x0),在0xffff80ffb9991116
=> [14] main(argc = 1,argv = 0xffff80ffbffffa78),第6行exampleMain.cpp






以下是重现此问题的最小示例:



exampleMain.cpp:

  #include< clayer.h> 
#include< stdio.h>

int main(int argc,char ** argv)
{
if(!clayerCall())
printf(got exception \\\
);
else
printf(OK\\\
);
}

共享库标头:

  externC{

bool clayerCall();

} // end externC

/ p>

  #includeclayer.h

#include< exception>
#include< stdexcept>
#include< stdio.h>

externC{

bool clayerCall()
{
try
{
throw std :: runtime_error hhh);
return true;
}
catch(std :: exception& ex)
{
return false;
}
}

} // end extern c






cmake文件如下所示:



可执行文件

  project(exampleMain)
cmake_minimum_required(VERSION 2.8)
set(CMAKE_BUILD_TYPE Debug)
add_definitions(-m64 -fPIC)

include_directories(../ stackoverflow)

link_directories(
../stackoverflow


add_executable(示例exampleMain.cpp)
target_link_libraries(
example
stdc ++
clayer


$ b b


cmake_minimum_required(VERSION 2.8)
cmake_policy(bayer)





$ b VERSION 2.8)
set(CMAKE_BUILD_TYPE Debug)

add_library(
clayer SHARED
clayer.cpp


解决方案

异常处理需要库和链接器支持,Sun Studio C ++工具链和Gnu C ++方式它就像名称调整,你已经注意到两个工具链之间不同)。使用C链接在这里没有帮助,因为您链接的函数的实现取决于该异常处理设施。一般来说,在同一个可执行文件中不能使用由两个不同工具链构建的C ++代码。



如果您必须使用Sun Studio,因为您使用的是封闭源库只与Sun Studio兼容,你最简单的方法是使用Sun C ++编译器来构建只使用GNU C ++构建的库,并假定该库是开源的。这可能不是微不足道的,你可能需要从图书馆的作者获得支持。我已经这样做,当我不得不写一些小脚本,看起来像GNU C ++命令调用Sun编译器正确的标志。



如果这是在问题,您可能必须将您尝试在服务中使用的库打包,并使用某种RPC机制从您的Sun Studio编译代码访问它。



修改:由于链接的库已专门升级,因此此问题可能会有所帮助。总而言之,某些升级可能会与您的版本的Sun编译器构建。


I need to build an application with Sun Studio. This application uses a shared library which can only be build with Gnu C++. The shared lib has a C Interface, so that the code is callable by the Sun Compiler (this is to avoid name mangling issues, see also this question).

Everything besides exception handling works fine. When an exception is thrown in the shared library, the program segfaults. This happens only when the main program is compiled using the Sun Studio Compiler. Compiling the minimal example below with the Gnu C++ compiler, the program works fine and the shared lib detects the exception.

Plan A: link dynamically Here is an illustration of the setup:

GCC                       SOLARIS STUDIO
                shared
c_layer.so      <-----    application
(no exceptions)           (uses exceptions sol studio)
   |
   | use flag -static -static-libstdc++ -static-lib-gcc
   v
gcc_only_lib.so
libstdc++.so
(uses gcc exceptions)

Result: segmentation violation once an exception is thrown (see code below).

Plan B: link statically

as above, but building c_layer.a

Result:

Undefined first referenced symbol
in file __cxa_allocate_exception libs/cInterface/libcInterface.a(c_layer.cpp.o) std::string::~std::basic_string () libs/cInterface/libcInterface.a(c_layer.cpp.o) __cxa_end_catch libs/cInterface/libcInterface.a(c_layer.cpp.o) __cxa_free_exception libs/cInterface/libcInterface.a(c_layer.cpp.o) __cxa_begin_catch libs/cInterface/libcInterface.a(c_layer.cpp.o) __cxa_throw libs/cInterface/libcInterface.a(c_layer.cpp.o)

Question: Why doesn't the exeption handling work with Sun Studio?


If I enforce the gcc runtime like this:

LD_PRELOAD=/usr/sfw/lib/amd64/libgcc_s.so ./example

it crashes differently:

$> terminate called after throwing an instance of 'std::runtime_error' $> terminate called recursively

(dbx) where 1 __lwp_sigqueue(0x1, 0x6, 0xffffc1000bae5060, 0xffffffff, 0x0, 0xffff80ffbffff810), at 0xffff80ffbf51e70a [2] thr_kill(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xffff80ffbf512ec8 [3] raise(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xffff80ffbf4c291d [4] abort(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xffff80ffbf497ff2 [5] __gnu_cxx::__verbose_terminate_handler(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xffff80ffbd9de911 [6] __cxxabiv1::__terminate(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xffff80ffbd9dbd5b [7] std::terminate(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xffff80ffbd9dbda3 [8] __cxa_rethrow(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xffff80ffbd9dc02d [9] __gnu_cxx::__verbose_terminate_handler(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xffff80ffbd9de8d4 [10] __cxxabiv1::__terminate(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xffff80ffbd9dbd5b [11] std::terminate(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xffff80ffbd9dbda3 [12] __cxa_throw(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xffff80ffbd9dbfd6 [13] clayerCall(0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xffff80ffb9991116 =>[14] main(argc = 1, argv = 0xffff80ffbffffa78), line 6 in "exampleMain.cpp"


Here is a minimal example to reproduce the problem:

exampleMain.cpp:

#include <clayer.h> 
#include <stdio.h>

int main(int argc, char **argv)
{
    if (!clayerCall())
        printf("got exception\n");
    else
        printf("OK\n");
}

shared lib header:

extern "C" {

bool clayerCall();

} // end extern "C" 

shared lib source:

#include "clayer.h"

#include <exception>
#include <stdexcept>
#include <stdio.h>

extern "C" {

bool clayerCall()
{
    try
    {
        throw std::runtime_error("hhh");
        return true;
    }
    catch (std::exception &ex)
    {
        return false;
    }
}

} // end extern c


The cmake files look like this:

for the executable

project(exampleMain)
cmake_minimum_required(VERSION 2.8)
set(CMAKE_BUILD_TYPE Debug)
add_definitions(-m64 -fPIC)

include_directories(../stackoverflow)

link_directories (
   ../stackoverflow
)

add_executable(example exampleMain.cpp)
target_link_libraries(
    example
    stdc++
    clayer
)

for the library

project(clayer)
cmake_minimum_required(VERSION 2.8)
cmake_policy(VERSION 2.8)
set(CMAKE_BUILD_TYPE Debug)

add_library(
    clayer SHARED
    clayer.cpp
)

解决方案

Exception handling requires library and linker support which differs between Sun Studio C++ tool chain and Gnu C++ (In this way it is like name mangling, which you've already noted differs between the two tool chains). Using "C" linkage doesn't help you here, because the implementations of the functions you are linking to depend on that exception handling facility. You can't in general use C++ code built with two distinct tool chains within the same executable.

If you have to use Sun Studio because you are using closed-source libraries that are only compatible with Sun Studio, your easiest way forward is probably to get the library that "only builds with GNU C++" to build with the Sun C++ compiler, presuming that that library is open source. This might not be trivial and you might need to get support from the library's authors. I've done this when I had to by writing little scripts that look like GNU C++ commands that invoke the Sun compiler with the correct flags.

If that is out of the question, you might have to wrap the library you're trying to use in a service and use an RPC mechanism of some sort to access it from your Sun Studio compiled code.

Edit: Since the library linked to is specifically boost, this question might be helpful. In summary, some pieces of boost might build with your version of the Sun compiler.

这篇关于Sun Studio链接gcc libs:例外不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆