Forum
    • Categories
    • Register
    • Login
    1. Home
    2. versusjona
    3. Best
    V
    • Profile
    • Following 0
    • Followers 0
    • Topics 4
    • Posts 9
    • Groups 0

    Posts

    Recent Best Controversial
    • Use-after-free in DelayedRenderer::processWrapped - crashes the DAW on dense MIDI (patch included)

      Hi all,

      I've been building a multi-mic drum kit, and for days it randomly crashed my DAW whenever I played fast, busy patterns (quick hi-hats, fast toms). It happened in both Ableton and Reaper, but never in the HISE standalone, which is what made it so hard to pin down. Windows reported heap corruption (0xC0000374), and the denser the MIDI, the faster it died, sometimes seconds, sometimes 10 minutes.

      I spent past Sunday debugging it with Claude Code, mostly to read the crash dumps for me.

      Things we ruled out first, in case it saves anyone time: my scripts (it still crashed with everything disabled), round-robin, choke scripts, voice limits, monoliths vs streamed samples, CPU affinity, deferCallbacks, and the number of samplers. It even crashed with a stripped-down project and an empty script, so it clearly wasn't my code.

      We eventually ran it under Application Verifier (PageHeap), which turns the delayed heap corruption into an immediate access violation, and symbolicated the dump. Here's what Claude Code found, pasting its explanation:

      The crash is in hi_core/hi_core/MainControllerHelpers.cpp, in DelayedRenderer::processWrapped.

      When the host sends a buffer larger than the prepared block size (the "FL Studio violates the block size" workaround), the function chunks the buffer and calls itself recursively — passing its own member delayedMidiBuffer as the midiMessages argument:

      processWrapped(chunk, delayedMidiBuffer);   // passes the member
      

      So inside the recursive call, midiMessages is delayedMidiBuffer. Then in the shortBuffer paths:

      MidiBuffer::Iterator it(midiMessages);   // iterator into delayedMidiBuffer
      delayedMidiBuffer.clear();               // clears the buffer being iterated
      for (auto& e : shortBuffer)
          delayedMidiBuffer.addEvent(...);     // and reallocs it
      while (it.getNextEvent(m, pos))          // dangling iterator -> use-after-free
      

      The clear() and reallocating addEvent() invalidate the iterator, which is then dereferenced. It only appears in a host because the standalone uses a fixed block size, so that recursive path never runs.


      The fix (give the recursion its own buffer so the two can't alias):

      // MainControllerHelpers.h — next to delayedMidiBuffer:
      MidiBuffer chunkMidiBuffer;
      
      // MainControllerHelpers.cpp — in the oversized-buffer branch:
      chunkMidiBuffer.clear();
      chunkMidiBuffer.addEvents(midiMessages, thisOffset, numThisTime, -thisOffset);
      ...
      processWrapped(chunk, chunkMidiBuffer);   // was: delayedMidiBuffer
      

      There are two shortBuffer paths that clear/regrow delayedMidiBuffer while iterating midiMessages, so this closes both.

      Result: my full kit used to crash within seconds or minutes. After the patch it ran +25 minutes in Reaper with PageHeap still on (so any remaining bad access would fault immediately) and +25 minutes in Ableton on the exact project that always crashed. No crash.

      Minor side note it also spotted: alloca(numChannels * sizeof(float*) * numChannels) in the same function allocates numChannels² — harmless, but looks like a typo.

      Hope it's useful information. Thanks for HISE!
      Jon

      posted in Bug Reports
      V
      versusjona
    • compileWithDebugSymbols breaks the export on Windows (malformed XML)

      Small bug, but it blocked me for a while: enabling Project Settings → CompileWithDebugSymbols makes the export fail on Windows with:

      xml parsing error, expected '=' after attribute '1'

      The cause (found while debugging something else): in hi_backend/backend/ProjectTemplate.cpp, the %STRIP_SYMBOLS_WIN% placeholder sits inside the quoted prebuildCommand attribute:

      prebuildCommand="%PREBUILD_COMMAND%;%STRIP_SYMBOLS_WIN%"/>
      

      but what gets substituted into it is itself a set of quoted XML attributes:

       alwaysGenerateDebugSymbols="1" debugInformationFormat="ProgramDatabase"
      

      so the inner quote closes the attribute early and the parser trips on the 1. With the setting off it substitutes an empty string, which is why nobody hits it normally.

      Fix: move the placeholder outside the quotes, matching how %STRIP_SYMBOLS_MACOS% is already written elsewhere in the same file:

      prebuildCommand="%PREBUILD_COMMAND%"%STRIP_SYMBOLS_WIN%/>
      

      Same fix applies in StandaloneProjectTemplate.cpp (line ~66), which has the identical issue.

      Worth fixing since this option is exactly what you need when you're trying to debug a crash, it's what was stopping me from getting usable symbols in the first place.

      Best,
      Jon

      posted in Bug Reports
      V
      versusjona