Boost crashing ableton on mac OS

anyone ever gotten crashes related to boost/asio within ableton?

I heard it might be due to clashing boost versions - so I switched to statically linking boost, and I’m still getting crashes

My audio plugin works fine in all DAWs, but Ableton.

Boost 1.81.0 used in plugin
Ableton Live 11.2.7
Mac OS 12.6.2 Monterey

EXC_BAD_ACCESS (code=1, address=0x10c)
at boost::asio::detail::scheduler::concurrency_hint

int concurrency_hint() const
{
  return concurrency_hint_;
}

Sorry, I’ve not heard of that crash. Can you say what version of Juce you are using?

Juce 7

I just dealt with a similar crash, but it was non-Boost ASIO (standalone version), however your error looks very similar to mine, check out my answer to see if you can figure out a similar fix:

Thanks for this, I’ve been baffled by this issue. Do you have a TLDR for why it crashes only in ableton?
And is the only fix to manually edit the boost source code?
Is this a bug in the ASIO library?

I don’t know why it’s only on Ableton in macOS, but I can give a little bit of insight into the crash - it sounds very similar to what happened in my scenario.

The TLDR is that it seems to have to do with how symbols are resolved (or not resolved) when dynamically loading Boost (or in my case non-Boost ASIO) code into some host processes on macOS. In my case if you just properly export them using the appropriate declaration, it fixes the issue and they resolve correctly.

Some static methods fail to have their memory address resolve correctly when turned into function pointer arguments used by some factory patterns to create instances of things like services. Since the function pointer’s memory address does not point correctly to the address of the static methods, calling them fails, and downstream objects end up uninitialized. When code then inevitably tries to access those uninitialized objects, you end up with the EXC_BAD_ACCESS crash, such as the concurrency_hint() getter.

In my case, I had to figure out where the factory method function pointer failed to resolve the address correctly. That showed me the static method that wasn’t resolving. It was service_registry::create - I went to its header file/declaration and noticed it wasn’t exported (in this case ASIO_DECL). However, the matching service_registry::destroy method was exported with ASIO_DECL, so I just added it to the definition of the method that failed to resolve. After that, there was no crash and everything worked as expected.

The evidence seems to be it’s more than just Ableton, as others on stackoverflow had the same issue when dynamically loading Boost code into some host processes on macOS.

If you can properly debug the Ableton process in Xcode, you should be able to look for these kinds of patterns, for me it looked like this:

template <typename Service>
Service& service_registry::use_service(io_context& owner)
{
  execution_context::service::key key;
  init_key<Service>(key, 0);
  factory_type factory = &service_registry::create<Service, io_context>;
  return *static_cast<Service*>(do_use_service(key, factory, &owner));
}

Here, the address of the create method resolves correctly in some DAWs, like Reaper or Tracktion, for example, and when I put a breakpoint and inspect the value of factory, XCode shows me the correctly reference and line number to the create method. But, when run from Ableton, there is no line number, and it points to some other object on the stack, incorrectly.

I would suggest looking for a similar pattern, since the error sounds similar, and then look for the declaration and export it.

In my case it was this:

// Factory function for creating a service instance.
template <typename Service, typename Owner>
static execution_context::service* create(void* owner);

Turned into this:

// Factory function for creating a service instance.
template <typename Service, typename Owner>
ASIO_DECL static execution_context::service* create(void* owner);

… that fixed my issue and the address could correctly resolve.

Thanks for the comprehensive answer. I’ll try this change - my only concern is I’m statically linking boost

I guess you edit the ASIO source and recompile? Or is it just headers?

I was compiling ASIO stand-alone using ASIO.hpp, so I was compiling from source. I only had to at the ASIO_DECL to the service_registry header though, recompiled, and the concurrency_hint() crash did not occur.