<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Crash in ScriptDownloadObject destructor at plugin teardown (EXC_BAD_ACCESS 0x58) — 4.9.2, macOS]]></title><description><![CDATA[<p dir="auto">anyone has experience with this?</p>
<p dir="auto">We have reason to believe that this could be fixed only inside HISE. Looking to confirm this with a HISE specialist<br />
thank you</p>
<p dir="auto"><strong>Report:</strong><br />
Crash on destroying ScriptDownloadObject — HISE 4.9.2, macOS arm64<br />
EXC_BAD_ACCESS (SIGSEGV), KERN_INVALID_ADDRESS at 0x0000000000000058</p>
<p dir="auto">Destroying a ScriptDownloadObject crashes inside its own base-class destructor chain. It happens wherever the destruction occurs — on the server thread during a run, or on the message thread at plugin teardown.</p>
<p dir="auto">Roughly 25 reproductions across three builds. Symbolicated against the exact binaries that crashed.</p>
<p dir="auto"><strong>The crash</strong><br />
Identical top four frames in every single report:</p>
<p dir="auto">juce::DynamicObject::~DynamicObject()                                 + 104<br />
hise::ApiClass::~ApiClass()                                           + 192<br />
hise::ScriptingObjects::ScriptDownloadObject::~ScriptDownloadObject() + 372<br />
hise::ScriptingObjects::ScriptDownloadObject::~ScriptDownloadObject() + 12<br />
The destructor body itself is trivial (ScriptingApiObjects.cpp:1172) and is not where it dies — +372 is inside the implicit base-class destruction that follows.</p>
<p dir="auto"><strong>Three call paths, same object</strong></p>
<ol>
<li>Message thread, at plugin close — the common case:</li>
</ol>
<p dir="auto">hise::JavascriptThreadPool::~JavascriptThreadPool() + 64<br />
hise::GlobalServer::~GlobalServer()                 + 12 / + 280<br />
hise::GlobalServer::WebThread::~WebThread()         + 176<br />
→ ScriptDownloadObject::~ScriptDownloadObject()   → crash<br />
2. Server thread, mid-run:</p>
<p dir="auto">juce::threadEntryProc(void*)              + 284<br />
hise::GlobalServer::WebThread::run()      + 5464<br />
→ ScriptDownloadObject::~ScriptDownloadObject()   → crash<br />
WebThread::run() copies pendingDownloads into a local ReferenceCountedArray thisList each iteration. When that local goes out of scope holding the last reference, the object is destroyed on the web thread.</p>
<ol start="3">
<li>Download thread — the same fault seen from the other side:</li>
</ol>
<p dir="auto">juce::threadEntryProc(void*)                                          + 284<br />
juce::FallbackDownloadTask::run()                                     + 100<br />
hise::ScriptingObjects::ScriptDownloadObject::progress(DownloadTask*, int64, int64) + 260<br />
juce::NamedValueSet::set(juce::Identifier const&amp;, juce::var const&amp;)   + 44<br />
KERN_INVALID_ADDRESS at 0x0 here. The object had already been destroyed and the still-running download task called progress() on it, writing into a NamedValueSet that no longer existed.</p>
<p dir="auto">So: destroy it while the task is live and the task writes into freed memory; destroy it later and the destructor itself dies.</p>
<p dir="auto"><strong>Reproduction</strong><br />
HISE 4.9.2, macOS 15.5, Apple Silicon, Cubase 15, VST3<br />
A plugin script that downloads a series of files via Server.downloadFile(), each subsequent download started from the previous one's completion callback<br />
16 downloads, ~150 MB total, real network transfers<br />
Crash on closing the plugin after the run completes<br />
Notes on reproducing it:</p>
<p dir="auto">Real transfers are required. If the target files already exist and resumeInternal short-circuits to success, nothing crashes.<br />
Frequency is high but not certain — roughly 15 crashes in 18 runs on the affected machine. It also occurred with only 4 downloads, so a long run is not needed.<br />
Not observed on several other machines, which may point at timing, host, or network speed.<br />
<strong>What we ruled out</strong><br />
Not the manifest or the URLs. Two different manifests, byte-identical addresses; a file that crashed one run downloaded cleanly the next.<br />
Not a shutdown timeout. HISE_SCRIPT_SERVER_TIMEOUT is 10000 ms and the thread appears to stop cleanly.<br />
Not fixable from HiseScript. Two attempts:<br />
Removing all Server.cleanFinishedDownloads() calls from the run. This removed the server-thread crashes (8 of 9 → 1 of 8) but the objects then survived to teardown and crashed there instead.<br />
Retaining a script-side reference to every download object, so HISE's ReferenceCountedArray would never be the last owner. No effect — and the stack shows why: GlobalServer is destroyed from JavascriptThreadPool::~JavascriptThreadPool(), so the script's own array is destroyed in the same operation. The refcount reaches zero regardless.<br />
<strong>What it looks like from outside</strong><br />
The object's DynamicObject base appears already invalid at the point of destruction — consistent with a double release, or with the object being released after something it depends on has gone.</p>
]]></description><link>https://forum.hise.audio/topic/15017/crash-in-scriptdownloadobject-destructor-at-plugin-teardown-exc_bad_access-0x58-4-9-2-macos</link><generator>RSS for Node</generator><lastBuildDate>Sat, 22 Aug 2026 22:25:36 GMT</lastBuildDate><atom:link href="https://forum.hise.audio/topic/15017.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 22 Aug 2026 19:07:53 GMT</pubDate><ttl>60</ttl></channel></rss>