[SOLVED] Random Crashes on ValueTrees while porting Intel x86 (macOS) app to ARM (iPad)

Hi all,

I’m about to port my macOS (Intel) app to the iPad. When running in the simulator (Intel MacBook Pro), everything is working fine. But when testing on the device, it crashes and the stack trace doesn’t give me any reasonable hint what is happening. I have one reproducible crash with a dedicated component while starting the app. It’s always on GetGlyphData().

When commenting out the repaint of this component, the app starts but I got random crashes with different errors all over the codebase. Example, it crashes on juce_String

static void release (StringHolder* const b) noexcept
    {
        if (! isEmptyString (b))
            if (--(b->refCount) == -1)
                delete[] reinterpret_cast<char*> (b);
    }

lldb says:

malloc: *** error for object 0x18f44f40: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
*** error for object 0x18f44f40: pointer being freed was not allocated

But sometimes already by simply trying to paint something (I don’t even see WHAT is repainting)

My strong opinion is that there is a severe threading issues somewhere. But I have no clue wehre to start searching.

Thanks
Stefan

If you haven’t tried this already, it’s probably a good idea to recompile with Address Sanitizer and Thread Sanitizer enabled.These can’t be enabled simultaneously, so you will need to test with each in turn. If the problem is due to a threading issue or memory access issue in your code (or the framework code), these tools should be able to give you more detailed diagnostic information about the problem. If these tools don’t provide any additional information, that might indicate that the first problem occurs in system code, which might indicate a problem in JUCE’s use of the system APIs.

To enable the sanitizers, go to the ‘scheme’ dropdown in Xcode’s top bar, then select “Edit Scheme…”, “Run” (in the left column), “Diagnostics” (tab on the right hand side), then pick Address Sanitizer or Thread Sanitizer.

thanks reuk, very good advice.
I was already messing around with Thread Sanitizer the whole afternoon but Address Sanitizer did bring a lot of stuff up. And (of course) it doesn’t seem to have anything to do with ARM/Intel or multithreading, the issues seems to rely on ValueTree callbacks and Identifier.


**=================================================================**

**==27345==ERROR: AddressSanitizer: heap-use-after-free on address 0x61f0000763b8 at pc 0x000106692420 bp 0x7ffeee10bcd0 sp 0x7ffeee10b498**

**READ of size 8 at 0x61f0000763b8 thread T0**

**#0 0x10669241f in __asan_memcpy+0x1af (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x4241f)**

**#1 0x101b03a24 in juce::String::getCharPointer() const juce_String.h:1153**

**#2 0x101afeaff in juce::Identifier::operator==(juce::Identifier const&) const juce_Identifier.h:78**

**#3 0x101afe821 in MeterArrayComponent::valueTreePropertyChanged(juce::ValueTree&, juce::Identifier const&) MeterArrayComponent.cpp:172**

**#4 0x102523e8a in juce::ValueTree::SharedObject::sendPropertyChangeMessage(juce::Identifier const&, juce::ValueTree::Listener*)::'lambda'(juce::ValueTree::Listener&)::operator()(juce::ValueTree::Listener&) const juce_ValueTree.cpp:100**

**#5 0x102523c70 in void juce::ListenerList<juce::ValueTree::Listener, juce::Array<juce::ValueTree::Listener*, juce::DummyCriticalSection, 0> >::callExcluding<juce::ValueTree::SharedObject::sendPropertyChangeMessage(juce::Identifier const&, juce::ValueTree::Listener*)::'lambda'(juce::ValueTree::Listener&)&>(juce::ValueTree::Listener*, juce::ValueTree::SharedObject::sendPropertyChangeMessage(juce::Identifier const&, juce::ValueTree::Listener*)::'lambda'(juce::ValueTree::Listener&)&) juce_ListenerList.h:156**

**#6 0x102523989 in void juce::ValueTree::SharedObject::callListeners<juce::ValueTree::SharedObject::sendPropertyChangeMessage(juce::Identifier const&, juce::ValueTree::Listener*)::'lambda'(juce::ValueTree::Listener&)>(juce::ValueTree::Listener*, juce::ValueTree::SharedObject::sendPropertyChangeMessage(juce::Identifier const&, juce::ValueTree::Listener*)::'lambda'(juce::ValueTree::Listener&)) const juce_ValueTree.cpp:85**

**#7 0x1025235dc in void juce::ValueTree::SharedObject::callListenersForAllParents<juce::ValueTree::SharedObject::sendPropertyChangeMessage(juce::Identifier const&, juce::ValueTree::Listener*)::'lambda'(juce::ValueTree::Listener&)>(juce::ValueTree::Listener*, juce::ValueTree::SharedObject::sendPropertyChangeMessage(juce::Identifier const&, juce::ValueTree::Listener*)::'lambda'(juce::ValueTree::Listener&)) const juce_ValueTree.cpp:94**

**#8 0x102505c9e in juce::ValueTree::SharedObject::sendPropertyChangeMessage(juce::Identifier const&, juce::ValueTree::Listener*) juce_ValueTree.cpp:100**

**#9 0x1025026db in juce::ValueTree::SharedObject::setProperty(juce::Identifier const&, juce::var const&, juce::UndoManager*, juce::ValueTree::Listener*) juce_ValueTree.cpp:138**

**#10 0x102502511 in juce::ValueTree::setPropertyExcludingListener(juce::ValueTree::Listener*, juce::Identifier const&, juce::var const&, juce::UndoManager*) juce_ValueTree.cpp:773**

**#11 0x102502401 in juce::ValueTree::setProperty(juce::Identifier const&, juce::var const&, juce::UndoManager*) juce_ValueTree.cpp:763**

**#12 0x101b8886e in juce::CachedValue<int>::setValue(int const&, juce::UndoManager*) juce_CachedValue.h:251**

**#13 0x101b88590 in juce::CachedValue<int>::operator=(int const&) juce_CachedValue.h:241**

**#14 0x101b884ae in NavigationButtonComponent::NavigationButtonComponent(juce::ValueTree, int)::$_0::operator()() const NavigationButtonComponent.cpp:15**

**#15 0x101b882ac in decltype(std::__1::forward<NavigationButtonComponent::NavigationButtonComponent(juce::ValueTree, int)::$_0&>(fp)()) std::__1::__invoke<NavigationButtonComponent::NavigationButtonComponent(juce::ValueTree, int)::$_0&>(NavigationButtonComponent::NavigationButtonComponent(juce::ValueTree, int)::$_0&) type_traits:3694**

**#16 0x101b8825c in void std::__1::__invoke_void_return_wrapper<void, true>::__call<NavigationButtonComponent::NavigationButtonComponent(juce::ValueTree, int)::$_0&>(NavigationButtonComponent::NavigationButtonComponent(juce::ValueTree, int)::$_0&) __functional_base:348**

**#17 0x101b8822c in std::__1::__function::__alloc_func<NavigationButtonComponent::NavigationButtonComponent(juce::ValueTree, int)::$_0, std::__1::allocator<NavigationButtonComponent::NavigationButtonComponent(juce::ValueTree, int)::$_0>, void ()>::operator()() functional:1558**

**#18 0x101b84978 in std::__1::__function::__func<NavigationButtonComponent::NavigationButtonComponent(juce::ValueTree, int)::$_0, std::__1::allocator<NavigationButtonComponent::NavigationButtonComponent(juce::ValueTree, int)::$_0>, void ()>::operator()() functional:1732**

**#19 0x102118deb in std::__1::__function::__value_func<void ()>::operator()() const functional:1885**

**#20 0x1020b46d4 in std::__1::function<void ()>::operator()() const functional:2560**

**#21 0x102b800f6 in juce::Button::sendClickMessage(juce::ModifierKeys const&) juce_Button.cpp:425**

**#22 0x102b8134e in juce::Button::internalClickCallback(juce::ModifierKeys const&) juce_Button.cpp:368**

**#23 0x102b82a3f in juce::Button::mouseUp(juce::MouseEvent const&) juce_Button.cpp:490**

**#24 0x102b314ee in juce::Component::internalMouseUp(juce::MouseInputSource, juce::PointerState const&, juce::Time, juce::ModifierKeys) juce_Component.cpp:2575**

**#25 0x102e5ed70 in juce::MouseInputSourceInternal::sendMouseUp(juce::Component&, juce::PointerState const&, juce::Time, juce::ModifierKeys) juce_MouseInputSource.cpp:140**

**#26 0x102e5529a in juce::MouseInputSourceInternal::setButtons(juce::PointerState const&, juce::Time, juce::ModifierKeys) juce_MouseInputSource.cpp:185**

**#27 0x102b48401 in juce::MouseInputSourceInternal::handleEvent(juce::ComponentPeer&, juce::Point<float>, juce::Time, juce::ModifierKeys, float, float, juce::PenDetails) juce_MouseInputSource.cpp:312**

**#28 0x102b47671 in juce::MouseInputSource::handleEvent(juce::ComponentPeer&, juce::Point<float>, long long, juce::ModifierKeys, float, float, juce::PenDetails const&) juce_MouseInputSource.cpp:609**

**#29 0x102de032f in juce::ComponentPeer::handleMouseEvent(juce::MouseInputSource::InputSourceType, juce::Point<float>, juce::ModifierKeys, float, float, long long, juce::PenDetails, int) juce_ComponentPeer.cpp:90**

**#30 0x10303adae in juce::NSViewComponentPeer::sendMouseEvent(NSEvent*) juce_mac_NSViewComponentPeer.mm:791**

**#31 0x10303f42a in juce::NSViewComponentPeer::redirectMouseUp(NSEvent*) juce_mac_NSViewComponentPeer.mm:673**

**#32 0x103038605 in void juce::JuceNSViewClass::callOnOwner<void (juce::NSViewComponentPeer::*)(NSEvent*), NSEvent*&>(objc_object*, void (juce::NSViewComponentPeer::*&&)(NSEvent*), NSEvent*&) juce_mac_NSViewComponentPeer.mm:2236**

**#33 0x10300d5fd in juce::JuceNSViewClass::asyncMouseUp(objc_object*, objc_selector*, NSEvent*) juce_mac_NSViewComponentPeer.mm:2241**

**#34 0x10300d796 in juce::JuceNSViewClass::mouseUp(objc_object*, objc_selector*, NSEvent*) juce_mac_NSViewComponentPeer.mm:2265**

**#35 0x7fff22e79044 in -[NSWindow(NSEventRouting) _reallySendEvent:isDelayedEvent:]+0xa9e (AppKit:x86_64+0x1c9044)**

**#36 0x7fff22e78385 in -[NSWindow(NSEventRouting) sendEvent:]+0x15a (AppKit:x86_64+0x1c8385)**

**#37 0x7fff22e76793 in -[NSApplication(NSEvent) sendEvent:]+0x15f (AppKit:x86_64+0x1c6793)**

**#38 0x7fff2314f530 in -[NSApplication _handleEvent:]+0x40 (AppKit:x86_64+0x49f530)**

**#39 0x7fff22cdf62d in -[NSApplication run]+0x26e (AppKit:x86_64+0x2f62d)**

**#40 0x102690c2e in juce::MessageManager::runDispatchLoop() juce_mac_MessageManager.mm:359**

**#41 0x102690a1e in juce::JUCEApplicationBase::main() juce_ApplicationBase.cpp:262**

**#42 0x1026906d5 in juce::JUCEApplicationBase::main(int, char const**) juce_ApplicationBase.cpp:240**

**#43 0x101c74641 in main Main.cpp:751**

**#44 0x7fff2040af3c in start+0x0 (libdyld.dylib:x86_64+0x15f3c)**

**0x61f0000763b8 is located 312 bytes inside of 2992-byte region [0x61f000076280,0x61f000076e30)**

**freed by thread T0 here:**

**#0 0x1066a0d1d in wrap__ZdlPv+0x7d (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x50d1d)**

**#1 0x101b7ec31 in NavigationButtonComponent::~NavigationButtonComponent() NavigationButtonComponent.cpp:50**

**#2 0x1031b2f6c in std::__1::default_delete<juce::Component>::operator()(juce::Component*) const memory:1428**

**#3 0x102bf4845 in std::__1::unique_ptr<juce::Component, std::__1::default_delete<juce::Component> >::reset(juce::Component*) memory:1689**

**#4 0x1030c75d8 in std::__1::unique_ptr<juce::Component, std::__1::default_delete<juce::Component> >::~unique_ptr() memory:1643**

**#5 0x102bf4434 in std::__1::unique_ptr<juce::Component, std::__1::default_delete<juce::Component> >::~unique_ptr() memory:1643**

**#6 0x102c3a77b in juce::Viewport::deleteOrRemoveContentComp() juce_Viewport.cpp:198**

**#7 0x102c3aaf7 in juce::Viewport::setViewedComponent(juce::Component*, bool) juce_Viewport.cpp:211**

**#8 0x101ba219b in WindowSettingsPage::reloadBankSelectionComp()::$_1::operator()(int) const SettingsPages.cpp:110**

**#9 0x101b9db7c in WindowSettingsPage::reloadBankSelectionComp() SettingsPages.cpp:155**

**#10 0x101b9cfc5 in WindowSettingsPage::connectWidgets() SettingsPages.cpp:69**

**#11 0x101bc4882 in SettingsComponentBase::valueTreeChildAdded(juce::ValueTree&, juce::ValueTree&) SettingsPages.h:45**

**#12 0x10251e4fa in juce::ValueTree::SharedObject::sendChildAddedMessage(juce::ValueTree)::'lambda'(juce::ValueTree::Listener&)::operator()(juce::ValueTree::Listener&) const juce_ValueTree.cpp:106**

**#13 0x10251e2e0 in void juce::ListenerList<juce::ValueTree::Listener, juce::Array<juce::ValueTree::Listener*, juce::DummyCriticalSection, 0> >::callExcluding<juce::ValueTree::SharedObject::sendChildAddedMessage(juce::ValueTree)::'lambda'(juce::ValueTree::Listener&)&>(juce::ValueTree::Listener*, juce::ValueTree::SharedObject::sendChildAddedMessage(juce::ValueTree)::'lambda'(juce::ValueTree::Listener&)&) juce_ListenerList.h:156**

**#14 0x10251dff9 in void juce::ValueTree::SharedObject::callListeners<juce::ValueTree::SharedObject::sendChildAddedMessage(juce::ValueTree)::'lambda'(juce::ValueTree::Listener&)>(juce::ValueTree::Listener*, juce::ValueTree::SharedObject::sendChildAddedMessage(juce::ValueTree)::'lambda'(juce::ValueTree::Listener&)) const juce_ValueTree.cpp:85**

**#15 0x10251dc4c in void juce::ValueTree::SharedObject::callListenersForAllParents<juce::ValueTree::SharedObject::sendChildAddedMessage(juce::ValueTree)::'lambda'(juce::ValueTree::Listener&)>(juce::ValueTree::Listener*, juce::ValueTree::SharedObject::sendChildAddedMessage(juce::ValueTree)::'lambda'(juce::ValueTree::Listener&)) const juce_ValueTree.cpp:94**

**#16 0x10251d3ba in juce::ValueTree::SharedObject::sendChildAddedMessage(juce::ValueTree) juce_ValueTree.cpp:106**

**#17 0x10250191b in juce::ValueTree::SharedObject::addChild(juce::ValueTree::SharedObject*, int, juce::UndoManager*) juce_ValueTree.cpp:268**

**#18 0x10250146f in juce::ValueTree::copyPropertiesAndChildrenFrom(juce::ValueTree const&, juce::UndoManager*) juce_ValueTree.cpp:693**

**#19 0x101b3c024 in RemoteMeterSource::setSettingsToDefault() RemoteMeterSource.cpp:184**

**#20 0x101b3e764 in RemoteMeterSource::restartConnection(RemoteMeterSource::Connection const&) RemoteMeterSource.cpp:195**

**#21 0x101b2ceac in MeterSourceArray::changeConnectionSettings(int, juce::String) MeterSourceArray.cpp:130**

**#22 0x101b2b35a in MeterSourceArray::resetAllMeterSourceConnections() MeterSourceArray.cpp:115**

**#23 0x101b2c068 in MeterSourceArray::valueTreePropertyChanged(juce::ValueTree&, juce::Identifier const&) MeterSourceArray.cpp:68**

**#24 0x102523e8a in juce::ValueTree::SharedObject::sendPropertyChangeMessage(juce::Identifier const&, juce::ValueTree::Listener*)::'lambda'(juce::ValueTree::Listener&)::operator()(juce::ValueTree::Listener&) const juce_ValueTree.cpp:100**

**#25 0x102523c70 in void juce::ListenerList<juce::ValueTree::Listener, juce::Array<juce::ValueTree::Listener*, juce::DummyCriticalSection, 0> >::callExcluding<juce::ValueTree::SharedObject::sendPropertyChangeMessage(juce::Identifier const&, juce::ValueTree::Listener*)::'lambda'(juce::ValueTree::Listener&)&>(juce::ValueTree::Listener*, juce::ValueTree::SharedObject::sendPropertyChangeMessage(juce::Identifier const&, juce::ValueTree::Listener*)::'lambda'(juce::ValueTree::Listener&)&) juce_ListenerList.h:156**

**#26 0x102523989 in void juce::ValueTree::SharedObject::callListeners<juce::ValueTree::SharedObject::sendPropertyChangeMessage(juce::Identifier const&, juce::ValueTree::Listener*)::'lambda'(juce::ValueTree::Listener&)>(juce::ValueTree::Listener*, juce::ValueTree::SharedObject::sendPropertyChangeMessage(juce::Identifier const&, juce::ValueTree::Listener*)::'lambda'(juce::ValueTree::Listener&)) const juce_ValueTree.cpp:85**

**#27 0x1025235dc in void juce::ValueTree::SharedObject::callListenersForAllParents<juce::ValueTree::SharedObject::sendPropertyChangeMessage(juce::Identifier const&, juce::ValueTree::Listener*)::'lambda'(juce::ValueTree::Listener&)>(juce::ValueTree::Listener*, juce::ValueTree::SharedObject::sendPropertyChangeMessage(juce::Identifier const&, juce::ValueTree::Listener*)::'lambda'(juce::ValueTree::Listener&)) const juce_ValueTree.cpp:94**

**#28 0x102505c9e in juce::ValueTree::SharedObject::sendPropertyChangeMessage(juce::Identifier const&, juce::ValueTree::Listener*) juce_ValueTree.cpp:100**

**#29 0x1025026db in juce::ValueTree::SharedObject::setProperty(juce::Identifier const&, juce::var const&, juce::UndoManager*, juce::ValueTree::Listener*) juce_ValueTree.cpp:138**

**previously allocated by thread T0 here:**

**#0 0x1066a08fd in wrap__Znwm+0x7d (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x508fd)**

**#1 0x101ba213d in WindowSettingsPage::reloadBankSelectionComp()::$_1::operator()(int) const SettingsPages.cpp:110**

**#2 0x101b9db7c in WindowSettingsPage::reloadBankSelectionComp() SettingsPages.cpp:155**

**#3 0x101b9cfc5 in WindowSettingsPage::connectWidgets() SettingsPages.cpp:69**

**#4 0x101b9c14d in WindowSettingsPage::WindowSettingsPage(juce::ValueTree) SettingsPages.cpp:51**

**#5 0x101b9cc84 in WindowSettingsPage::WindowSettingsPage(juce::ValueTree) SettingsPages.cpp:5**

**#6 0x101bc3e1b in SettingsPreferencesPanel::createComponentForPage(juce::String const&) SettingsPages.cpp:1004**

**#7 0x1035ff8ac in SBPreferencesPanel::setCurrentPage(juce::String const&) SBPreferencesPanel.cpp:177**

**#8 0x1035fee76 in SBPreferencesPanel::addSettingsPage(juce::String const&, juce::Drawable const*, juce::DrawableButton::ButtonStyle) SBPreferencesPanel.cpp:91**

**#9 0x101c848c2 in SettingsWindow::SettingsWindow(juce::ValueTree) SettingsPages.h:670**

**#10 0x101c83e04 in SettingsWindow::SettingsWindow(juce::ValueTree) SettingsPages.h:651**

**#11 0x101c83b76 in MTRbridgeApplication::loadInspectorWindow(juce::ValueTree) Main.cpp:379**

**#12 0x101c81b0a in MTRbridgeApplication::Window::perform(juce::ApplicationCommandTarget::InvocationInfo const&) Main.cpp:228**

**#13 0x102e06cdc in juce::ApplicationCommandTarget::tryToInvoke(juce::ApplicationCommandTarget::InvocationInfo const&, bool) juce_ApplicationCommandTarget.cpp:65**

**#14 0x102fc62ae in juce::ApplicationCommandTarget::CommandMessage::messageCallback() juce_ApplicationCommandTarget.cpp:40**

**#15 0x1026c05ce in juce::MessageQueue::deliverNextMessage() juce_osx_MessageQueue.h:81**

**#16 0x1026c03c1 in juce::MessageQueue::runLoopCallback() juce_osx_MessageQueue.h:92**

**#17 0x1026bfd64 in juce::MessageQueue::runLoopSourceCallback(void*) juce_osx_MessageQueue.h:100**

**#18 0x7fff204e7ceb in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__+0x10 (CoreFoundation:x86_64h+0x80ceb)**

**#19 0x7fff204e7c53 in __CFRunLoopDoSource0+0xb3 (CoreFoundation:x86_64h+0x80c53)**

**#20 0x7fff204e79d3 in __CFRunLoopDoSources0+0xf1 (CoreFoundation:x86_64h+0x809d3)**

**#21 0x7fff204e63fb in __CFRunLoopRun+0x37c (CoreFoundation:x86_64h+0x7f3fb)**

**#22 0x7fff204e59bb in CFRunLoopRunSpecific+0x232 (CoreFoundation:x86_64h+0x7e9bb)**

**#23 0x7fff2872ea82 in RunCurrentEventLoopInMode+0x123 (HIToolbox:x86_64+0x30a82)**

**#24 0x7fff2872e6b5 in ReceiveNextEventCommon+0x11b (HIToolbox:x86_64+0x306b5)**

**#25 0x7fff2872e582 in _BlockUntilNextEventMatchingListInModeWithFilter+0x45 (HIToolbox:x86_64+0x30582)**

**#26 0x7fff22ceeb11 in _DPSNextEvent+0x35f (AppKit:x86_64+0x3eb11)**

**#27 0x7fff22ced2e4 in -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:]+0x553 (AppKit:x86_64+0x3d2e4)**

**#28 0x7fff22cdf608 in -[NSApplication run]+0x249 (AppKit:x86_64+0x2f608)**

**#29 0x102690c2e in juce::MessageManager::runDispatchLoop() juce_mac_MessageManager.mm:359**

Interestingly it didn’t throw any errors running on macOS (Intel) during the last months but the issues are there as well!

Will have to investigate further…

I actually had a seemingly similar issue with juce::Identifier: (BUT REPORT?) Identifier gets freed twice when App exits

I think you need to share a bit more about your code. Even though I couldn’t figure out the exact problem with my code, the main problem was simply using global variables (which should be avoided at best anyway).

SOLVED

Some ValueTree callbacks were connected to objects which were already deleted. A simple AsyncUpdater to link to the new ones did the trick.

Still not 100% sure why it didn’t crash on the macOS version. I suppose as the ValueTree callback order is not guaranteed to always be the same there was some difference…

Anyway, thanks to @reuk for the tip with Address Sanitiser, that’s a nice testing tool for such things :+1:

Thanks Rincewind for your feedback. I saw your post yesterday. And yes I use global Identifiers in IDs namespace across the app. I borrowed that approach from @dave96 and his amazing ValueTree presentation at ADC17.
But in my case that was not the issue. It seems (if I got that right) that sometimes the property variable (passed by reference) in the valueTreePropertyChanged callback was already deleted when the callback happened (not my Identifier). Or the callback wanted to change/delete stuff in objects that were already deleted. I don’t know, I have to admit. But using an AsyncUpdater helped me out and (until now) I couldn’t reproduce any address issues on any platform.