Issue with AudioProcessorValueTreeState::SliderAttachment after 5.2.1 update on macOS Sierra

I seem to be having an issue with SliderAttachment after the 5.2.1 update. It occurs while closing the plugin window. It worked perfectly fine before the update and I did not change a single thing after updating JUCE. I know there have been some changes in AudioProcessorValueTreeState, but not entirely sure about the details. Is there something new that I’m not taking into consideration?
To attach a slider, I simply use:
exampleSliderAttachment = new SliderAttachment (treeState, "paramName", *sliderToAttachTo);
I used ScopedPointer for both the slider and SliderAttachment.

More specifically, based on the debug session, it looks like it might have something to do with removing Listeners that are tied to SliderAttachment. This pops up right after I close the plugin window:

`/** Returns a raw pointer to the allocated data.
This may be a null pointer if the data hasn’t yet been allocated, or if it has been
freed by calling the free() method.
*/

inline ElementType* get() const noexcept                                 { return data; }`

with an EXC_BAD_ACCESS error.

If I’m understanding this correctly, it looks like this happens while removing listeners from an Array in the ListenerList class.
When I remove the SliderAttachments, the plugin closes properly and everything destructs with no issues. I also use ButtonAttachment and that still works fine. The issue only seems to occur when using SliderAttachment.

Maybe have a look on the order of your member variables. They will be destroyed in reverse order. So defining your Slider before the attachments could help. I always have the attachments defined last, so I can be sure they will be destroyed first.

If you can’t choose the order, you may enforce the deletion in your destructor by calling attachment.reset(); or simply assigning attachment = nullptr; at the beginning of the destructor.

HTH

1 Like

Hi Daniel,
Looks like the order of the member variables was the issue. I did assign attachment = nullptr; in the destructor, but the attachment was defined before the Slider. I defined it last and now it works, makes sense. I wonder why the order didn’t matter before the update. Somehow the order still doesn’t seem to matter for ButtonAttachment and ComboBoxAttachment, but still, I’ll put them last just to be safe. Thank you!!

Ah one more thing. One of my classes that uses the attachments is a GUI component, and it only allows me to add custom variables before the ones generated by the GUI editor (which includes mostly Sliders and Buttons). Is there a way around this? If not, then I might as well not use the editor in this case.

It is only a problem, if the attachment tries to access the slider after it’s being destructed, so it is sensitive to timing differences (actually it is undefined behaviour), so it was always a potential problem, and after the update it became an obvious problem.

sure, as I said, in your destructor call as first line explicitly attachment.reset(); which deletes the attachment, so there is no chance, it accesses the slider after deletion.

I don’t have a generated GUI component at hand, there is a custom code block at the beginning of destructor, isn’t it?

Good luck

Yes there is a block for custom code at the beginning and at the end of the destructor. I moved my attachment = nullptr; to the beginning under “Destructor_pre” and it works now.

Thank you so much Daniel!

i am facing the same problem but the attachment process you mention did not work out…

//[/Constructor_pre]

    addAndMakeVisible (FSlider = new Slider ("FREQ"));
    FSlider->setRange (1, 31, 1);
    FSlider->setSliderStyle (Slider::RotaryVerticalDrag);
    FSlider->setTextBoxStyle (Slider::NoTextBox, false, 120, 20);
    ...
    FSlider->addListener (this);


.....


//[Constructor] You can add your own custom stuff here..
    customSlider* lafobjct = new customSlider();
 	setLookAndFeel(lafobjct);
 	
 	//Create Value Tree State Attachments
	ParameterAttachment1 = new SliderAttachment(valueTreeState, "FParam", *FSlider);
	ParameterAttachment2 = new SliderAttachment(valueTreeState, "GainParam", *GainDbSlider);
    ParameterAttachment12 = new SliderAttachment(valueTreeState, "BatParam", *BatDbSlider);

	ToggleAttachment = new ButtonAttachment(valueTreeState, "x2", *toggleButton);
    //[/Constructor]

BatSimAudioProcessorEditor::~BatSimAudioProcessorEditor()
{
    //[Destructor_pre]. You can add your own custom destruction code here..
    //[/Destructor_pre]

    FSlider = nullptr;
    GainDbSlider = nullptr;
    BatDbSlider = nullptr;
    label = nullptr;
    label2 = nullptr;
    label3 = nullptr;
    imageButton = nullptr;
    toggleButton = nullptr;
    

    //[Destructor]. You can add your own custom destruction code here..

    ParameterAttachment1 = nullptr;
    ParameterAttachment2 = nullptr;
    ParameterAttachment12 = nullptr;
    ToggleAttachment = nullptr;

    
    deleteAllChildren();    // Just in case you miss something (maybe unneeded)
    //[/Destructor]
}

any ideas?

Same problem, same solution:

You delete the ToggleAttachment after the toggleButton, leaving the attachment the chance to use the deleted button.

Move the ToggleAttachment = nullptr; before toggleButton = nullptr; and accordingly for all others.

Also note, that capital names for objects are discouraged by convention. While there is no technical reason, it just makes it easier to read.

HTH

2 Likes

Thanks a lot. Problem solved!