Hi!
My application crashes when I delete a folder track containing one or more audio tracks during playback.
Interestingly Waveform 12 also crashes when I perform the actions mentioned above so I think the root cause might be in the engine.
This can be reproduced reliably (at least on the system I tested), especially with higher cpu loads / small buffer sizes (tested with 16 samples per block).
I’m using tracktion_engine at commit 47bea6093
, running on Windows 10.
Tested the following waveform versions:
Waveform Version 12.0.53 (Built: 21 March 2022) (64-bit)
Waveform Version 12.1.8 (Built: 28 October 2022) (64-bit)
I think the main issue is in tracktion_VolumeAndPanPlugin.cpp in getParentVcaDb()
:
for (FolderTrack::Ptr p = track.getParentFolderTrack(); p != nullptr; p = p->getParentFolderTrack())
{
// ...
}
As I understand getting a pointer to the parent and creating a FolderTrack::Ptr
from it is not atomic.
The ~FolderTrack
destructor might be called from the message thread but at that point track.getParentFolderTrack()
still returns a non-null pointer because it is not updated until Track::updateCachedParent
gets called.
So p
now points to an memory that is already freed by another thread and when it goes out of scope and calls the ~FolderTrack
destructor it will crash.
I would also like to make sure that I’m using the engine correctly. Are there any constraints on what one should or should not do with the reference-counted objects returned by the engine? In my app I keep a FolderTrack::Ptr
as a data member of a class derived from juce::Component
. Just like in the RecordingDemo.h
example, but with an addition of FolderTrack
.
Any guidelines on how to use all the reference counted objects that you can get from the engine?