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.