Symbol visibility in Mac OS libraries

I was having a nice coding day. Xcode was behaving nicely and all of my code seem to behave like I wanted to … then …

Crash. Okay. I can handle a crash. But. Looking at the call stack from the crash, something didn’t look right.

In the call stack there was a reference to the std::string class. But the function where the crash is happening doesn’t have any references to std::string.

What. Is. Going. On?

Okay. Time to pull up the debugging console and see what is going on.

I type “bt” in the GDB console… nothing unusual… other than the call to the phantom std::string.

So now I switch the debugger display to show both the source code and assembly code.

Nothing looks unusual stepping through the code… but… I don’t understand how std::string is being called.

I copied the Hex address where the crash is happening and back to the GDB debugger and I typed:

info shared 0X0SOMELONGHEX


To my surprise, the code had jumped to some other library that had nothing to do with my function.

Hold on here. Is this doing what I think it’s doing?

It seemed that during my application startup, one of the other dylibs that was loaded first had a reference to the same function my dylib was using, but an earlier version of the code. Both dylibs had the code statically linked in, but, they were both exposed.

Oh.

Well, that shouldn’t be too hard to fix. Just set the symbols to hidden:

GCC_SYMBOLS_PRIVATE_EXTERN = YES


Well that should have fixed my problems but I still had a lot of cleaning up to do. RTTI information was no longer easily accessible and libraries that depended on that accessible code no longer saw the symbols during the linker portion of compiling.

So, it seems that if you don’t hide your symbols, on the Mac that is, the dlopen app will match up symbols from two different libraries and pick the first one, even if they are private to the file and not exposed in any headers, causing a nice crash that produces a call stack that doesn’t make sense.

Oh. Kay. Lesson learned.

Leave a Reply

Your email address will not be published. Required fields are marked *