Note that there are some explanatory texts on larger screens.

plurals
  1. POHiding symbols in a shared library on Mac OS X
    primarykey
    data
    text
    <p>We've been building a large open source <a href="http://appleseedhq.net/" rel="noreferrer">software</a> on a variety of platforms (Linux, Windows, Mac OS X, 32-bit and 64-bit) for several years without troubles. Lately however, the Mac OS X build (64-bit) stopped working correctly and started to crash randomly. It more or less coincided with an update of Mac OS X on our build machine from 10.7 to 10.8.2 (but the compiler toolchain didn't change, it's still llvm-gcc 4.2.1).</p> <p>Our application is made of a couple of dynamic (shared) libraries and many executables using them. One of the shared library overrides the <code>new</code> and <code>delete</code> operators for a variety of reasons. On Mac OS X (and Linux), all symbols are exported by default, including our overloaded <code>new</code> and <code>delete</code> operators. The crashes on Mac OS X seem related to some memory being allocated with one memory subsystem (not ours) then freed through our own (and incompatible) <code>delete</code> implementation.</p> <p>The sanest solution seems to be preventing the overloaded operators from being visible to the users of the shared library. This can be accomplished in two ways: marking the operators with <code>__attribute__((visibility("hidden")))</code>, or using the <code>-unexported_symbols_list</code> linker command line option to prevent some symbols from being exported. The first solution unfortunately doesn't work: gcc emits warnings saying that the operators have been declared differently (in <code>&lt;new&gt;</code>) and thus the attributes will be ignored. From my readings in various places, <strong>the second solution seems to be the right one to this problem. However for some reason we can't make it work</strong>.</p> <p>When linking the shared library, we're passing the <code>-Wl,-unexported_symbols_list unexported_symbols_list.txt</code> option to g++, which in turns should be passed to ld. The <code>unexported_symbols_list.txt</code> file contains the following list of symbols:</p> <pre><code>__ZdaPv __ZdaPvRKSt9nothrow_t __ZdlPv __ZdlPvRKSt9nothrow_t __ZdlPvS_ __Znam __ZnamRKSt9nothrow_t __Znwm __ZnwmPv __ZnwmRKSt9nothrow_t </code></pre> <p>These are all the variations of <code>new</code> and <code>delete</code> that we override and want to be hidden. We found these symbols by doing <code>nm libappleseed.dylib</code> then unmangling the symbol names using <code>c++filt</code>.</p> <p>Here's the command line generated by CMake to link <code>libappeseed.dylib</code>:</p> <pre><code>/usr/bin/g++ -g -Werror -dynamiclib -Wl,-headerpad_max_install_names -framework Cocoa -lcurl -Werror -Wl,-unexported_symbols_list -Wl,unexported_symbols_list.txt -o ../mac-gcc4/appleseed/libappleseed.dylib [...] </code></pre> <p><strong>Unfortunately, despite all our efforts it appears that the symbols remain (as nm shows).</strong></p> <p>Any idea what we are doing wrong? Is there another approach that we could try?</p> <hr> <p><strong>UPDATE Dec. 19, 2012:</strong></p> <p>Our problem and the supposed solution are well covered in this technical note from Apple: <a href="http://developer.apple.com/library/mac/#technotes/tn2185/_index.html" rel="noreferrer">http://developer.apple.com/library/mac/#technotes/tn2185/_index.html</a> (section "Overriding new/delete").</p> <p>Pointers to relevant source code:</p> <ul> <li><code>operator new</code> and <code>operator delete</code> overrides: <a href="https://github.com/jupiter-jazz/appleseed/blob/0ae130df5750c468db80f7fcdae40bb82bc0b23a/src/appleseed/main/allocator.cpp#L480" rel="noreferrer">allocator.cpp</a></li> <li>Macros to control symbol visibility in the shared library: <a href="https://github.com/jupiter-jazz/appleseed/blob/a9fcc42c52548b01507823e966b2a4b5861f7af4/src/appleseed/main/dllvisibility.h#L33" rel="noreferrer">dllvisibility.h</a></li> </ul> <p>Fragment of <code>nm</code>'s output after building libappleseed.dylib with <code>-fvisibility=hidden</code> and running <code>strip -x libappleseed.dylib</code>:</p> <pre><code>... 00000000002a41b0 T __ZdaPv 00000000002a41f0 T __ZdaPvRKSt9nothrow_t 00000000002a4190 T __ZdlPv 00000000002a41d0 T __ZdlPvRKSt9nothrow_t 00000000002a4060 T __Znam 00000000002a4130 T __ZnamRKSt9nothrow_t 00000000002a3ff0 T __Znwm 00000000002a40d0 T __ZnwmRKSt9nothrow_t ... </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload