jeudi 23 juin 2016

DSO library symbol seems to have DEFAULT visibility although should be HIDDEN

I have a problem with setting up a visibility of my shared library. I would like to ask for help in resolving my issue as described below:

I have a bunch of source files which I would like to build as shared library:

+Base
|_Parameter
| |_Parameter.h
| |_Parameter_Exception.h
| |_Parameter_Exception.cpp
|_Data
| |_DataInput.h
| |_DataInput_Exception.h
| |_DataInput_Exception.cpp
...

Well there are some more files in there but I think it does not influence my problem description.

I am using CMake in order to build this SHARED library. Here is part of my CMakeLists.txt which deals with building the library.

project( Base )
cmake_minimum_required(VERSION 3.5

set( Base_HEADERS
    Parameter/Parameter.h
    Parameter/Parameter_Exception.h
    Data/DataInput.h
    Data/DataInput_Exception.h
)
set( Base_SOURCES
    Parameter/Parameter_Exception.cpp
    Data/DataInput_Exception.cpp
)
set( LIBRARY_OUTPUT_PATH ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} )

add_library( Base SHARED ${Base_SOURCES} ${Base_HEADERS} )

generate_export_header( ${PROJECT_NAME} EXPORT_FILE_NAME ${PROJECT_NAME}_Export.h )

This setup builds libBase.so shared library without any problem. It is important to mention that I have set some visibility related flags to be used during linking:

set( CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined -fvisibility=hidden -fvisibility-inlines-hidden" )

As configured in Base library CMakeLists.txt partly listed above:

  1. Base_Export.h header containig GCC visibility attributes macros is generated by CMake. It is then included in my sources listed in the tree up there.
  2. By default all the symbols shall be hidden as set in linker flags (-fvisibility=hidden)

For example a piece of Parameter_Exception.h:

#include "Base_Export.h"

class SomeException : public std::exception
{
public:
    SomeException( void ) {}
...
};

Please notice I have not set any visibility attribute here (by a macro defined in Base_Export). So I would assume, the symbol of SomeException class shall be hidden to all the DSO "users" (due to -fvisibility=hidden)

But it doesn't seem so. Unfortunately:

Once I use the library, it the exception is usable although the symbol should be hidden. I would expect link failure cause by this code snippet "outside the library":

#include "Parameter/Parameter_Exception.h"
...
try
{
    ...
}
/* THIS SHOULD FAIL IN LINKING DUE TO UNDEFINED SYMBOL, RIGHT? */
catch( const SomeException & e )
{
    ...
}

I have also tried to look for the symbol in the libBase.so using the command: readelf -Ws libBase.so

it lists enormously long text:

Num:    Value          Size Type    Bind   Vis      Ndx Name
  0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
  1: 000000000008b7e0     0 SECTION LOCAL  DEFAULT    9 
....

but what I have noticed here is that in "Vis" column up there there is always DEFAULT which implies a default visibility ( __attribute__((visibility("default"))) ) to me BUT I would expect to see HIDDEN in there ( __attribute__((visibility("hidden"))) )

So what am I doing wrong? Or my understanding is not correct? I know all the linked flags are propagated correctly but seem to have no effect.

My toolchain configuration as listed by CMake configuration script (GCC version that supports visibility attributes):

...
-- The CXX compiler identification is GNU 5.3.1
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
...
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY - Success
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY - Success
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR - Success
-- Configuring done
-- Generating done

Many thanks in advance to anybody willing to help me and possibly others having the same trouble as I do.

Thanks again, Martin

Aucun commentaire:

Enregistrer un commentaire