-1

I am really newbie with development for Mac and I faced with strange behavior, which I can't find how to deal with.

I have a mylib.dylib file, compiled with boost 1.80.0 as dependency, and an executable, that load the mylib.dylib and uses boost 1.66.0.

Boost statically linked in both cases. So, I expect that entire code inside the library is fully independent from executable binary. But it seems that Mac has another opinion).

When I call dlopen, some global object inside boost start to initialize and it's call boost::system::system_category() function. The function has absolutely different implementation in 1.66.0 and 1.80.0 versions. In short words, I realized that mylib.dylib calls system_category() from executable(1.66.0), not his own one(1.80.0).

Disassembly view proof: enter image description here

When I started to google the problem, I have found a comment that describe Flat-namespace and Two-level namespace concepts: https://stackoverflow.com/a/49392862/4481855 . And the behavior of my binaries looks like it's compiled as Flat-namespace as it seems that executable file already have system_category symbol which somehow forced mylib.dylib to use it instead his own one, but I checked both files via otool -hV and it shows TWOLEVEL for both.

I have tried to load mylib.dylib via dlopen with different flags and combinations, but no success.

One more clue is that symbol dumber says, that system_category is weak symbol in mylib.dylib:

% nm -m libcompliance_engine.dylib | grep weak | grep system_category
00000000022205c8 (__DATA,__data) weak external __ZGVZN5boost6system15system_categoryEvE8instance
0000000000178aa0 (__TEXT,__text) weak external __ZN5boost4asio5error19get_system_categoryEv
000000000007bed0 (__TEXT,__text) weak external __ZN5boost6system15system_categoryEv
0000000002220590 (__DATA,__data) weak external __ZZN5boost6system15system_categoryEvE8instance

What can I do to tell mylib.dylib to use his own implementation of system_category? Any suggestions would be helpful.

hdnn
  • 1,807
  • 3
  • 13
  • 20
  • *When I call `dlopen`, some global object inside boost start to initialize and it's call `boost::system::detail::system_category()` function.* It looks well working. mylib.dylib is linked with boost 1.80.0, `boost::system::detail::system_category()` is from boost 1.80.0. boost 1.66.0 has `boost::system::system_category()`, another namespace. mylib.dylib can't call it. – 273K Jun 07 '23 at 15:24
  • My bad, I wrote names from my memory and made the mistake - "global object" calls `boost::system::system_category()`, no `details` namespace there – hdnn Jun 07 '23 at 16:08
  • You are confusing something. `boost::system::system_category()` can't be called from mylib.dylib linked with `boost 1.80.0`. That name is unknown to the dylib library. You seem to have an issue in your code, and not in mylib.dylib initialization. You might set a breakpoint at `boost::system::system_category()` and watch the call stack. – 273K Jun 07 '23 at 16:21

1 Answers1

0

The problem also described as "potentially possible scenario" here: Two-level namespace and external symbols

Fortunately, my teammate has found the solution: it has been fixed in 1.81.0 version by implementing BOOST_DISABLE_EXPLICIT_SYMBOL_VISIBILITY definition, so after upgrading boost from 1.80.0 to 1.81.0 the issue disappeared, as system_category is not a weak symbol anymore

hdnn
  • 1,807
  • 3
  • 13
  • 20