forsitan modulare imber causing crashes

This is a problem very much worth solving, because imber, when it does work, is one of the most playful, unique, and immediately rewarding modules in recent memory. For those who haven’t tried it, I highly recommend giving it a try, if you can. Just send audio out and start turning knobs, you’ll quickly get the idea.

But as the title suggests, I’m having a tough time getting imber to initialize. VCVRack always crashes when I try to load it. If imber was successfully initialized before the crash, then it also initializes successfully on restarting VCVRack. But trying to initialize it from the module browser, it crashes every single time, and usually before imber can finish initializing.

The problem seems to have something to do with generating the samples; it also crashes when I press the button to reseed the sample bank.

Edit to add: sylla, which apparently uses the same sample generation procedure on a single voice, does not cause crashes.

Running Ubuntu 24.04.4 if that’s possibly relevant. Edit to add: I suspect this is very relevant, because imber loads just fine on my much slower, older Windows laptop.

One more edit: imber loads fine as long as my audio interface is set to “no device.” This suggests it has more to do with the way Jack is handling the application than anything VCVRack or imber is doing wrong. My hopes of a quick fix are dimming, but also it’s a very easy workaround, with the caveat that I can’t reseed the samples live.

I’ll second that.

I have had no issues (so far) running these on either Mac or Windows. Will certainly report back if I do.

@nolente … thanks for these great modules!! Cheers!!

The OS is always relevant.

Nope, it doesn’t. It could be a Jack issue, but more likely it’s an Imber issue. See, what happens when no audio device is selected is that no processing occurs in the module, only the GUI is shown but it’s not actually doing anything. To me this strongly suggests that the problem is in the processing/DSP of the module, and on top of that it’s specific to Linux where it might not have been tested.

You should attach your log.txt file so people can comb over it.

@jakulley thanks for the report and for trying imber! I’ll look into it, it would be helpful if you could recover the log.txt file from the vcvrack folder after a crash.

I tried building it (master-v2 branch and also v2.13.1 tag) on Linux, but the build failed, so I couldn’t run it under Linux to maybe find out where it crashes.

src/limen.cpp: In member function ‘virtual void LimenWidget::step()’: src/limen.cpp:1079:49: error: ‘struct rack::app::RackScrollWidget’ has no member named ‘zoomToModules’ 1079 | APP->scene->rackScroll->zoomToModules();

log.txt (60.7 KB)

Here’s log.txt after recreating the crash this morning.

Found it, and it is neither Jack nor the generators. It is where the generator thread comes from.

imber starts its bank render from process(), which is the audio callback thread, and under Jack or PipeWire that thread is SCHED_FIFO. On Linux a new thread inherits the scheduling policy of the thread that created it, so the render came up realtime too and then ran for hundreds of milliseconds without ever blocking. RTKit grants realtime priority only with a cap on uninterrupted realtime CPU, normally 200 ms, and the kernel enforces that cap with SIGXCPU, which kills the process. A full bank is 388 ms of solid CPU here. That is the crash.

The rest follows. On “no device” the engine never runs, so no bank is ever generated and there is nothing to kill. sylla renders one buffer instead of 192, at worst 90 ms, which fits inside the cap: same bug, just under the limit rather than over it. And it is why I never saw it here, on a machine with no realtime audio at all.

So do not go hunting for a log, jakulley. SIGXCPU kills outright, and log.txt just stops mid-line with nothing after it. coredumpctl is where the evidence would be.

Fixed in 2.13.2: both modules now ask for ordinary priority for the worker instead of inheriting the audio thread’s. Same render at the same speed, but it can no longer be killed by, or starve, the audio thread. The one visible difference is that on a busy machine a bank may take slightly longer to appear.

I cannot reproduce the bug here, so I cannot verify the fix here either. Before I send it to the library, @jakulley two things if you have time:

  1. On 2.13.2, with your usual Jack setup, add imber from the browser fifteen or twenty times, then hit RESEED twenty or thirty times. Both used to be able to kill it within a few tries.
  2. Tell me what the audio path actually is, PipeWire’s Jack or jackd2, and what ulimit -r -l reports. I would like the triggering configuration written down somewhere.

@fiddlercrabseason a quick check that nothing regressed on Mac or Windows would be welcome if you are willing. Neither should be affected, but the change touches both modules’ worker threads.

@OldPluginGuy yours is unrelated, and undocumented on my side, which is my fault. RackScrollWidget::zoomToModules() arrived in Rack 2.6.0 and limen uses it, so an older SDK cannot build the plugin. Fetch Rack-SDK 2.6.6 from VCV - Downloads , point RACK_DIR at it, and it should compile. Or skip the build entirely and take a binary from the release below.

Build: Release Release v2.13.2 · gosub/forsitan-modulare · GitHub Take the lin-x64 .vcvplugin, drop it in ~/.local/share/Rack2/plugins/, restart Rack. It is deliberately not in the library yet.

Thank you for the report. A crash that only fires under a realtime audio stack is exactly the sort of thing I would never have found on my own machine.

Learned something new about Threads on Linux.

No more need to build it now, I only wanted to reproduce the crash in the debugger, but since it is all solved now…

If I built 2.13.2 correctly (usually I just use the VCVRack library to get my modules, but I’m pretty sure I did, the context menu lists the modules as 2.13.2), it didn’t fix the bug. Sorry!

My audio path is jackd2.

ulimit -r -l:

real-time priority (-r) 95 max locked memory (kbytes, -l) unlimited

@jakulley two small things and one that matters most.

Your log ends on this line:

[150.696 info src/app/ModuleWidget.cpp:594 load] Loading preset /home/jakulley/.local/share/Rack2/presets/forsitan/imber/template.vcvm

So you have imber saved as your default template, which means every add from the browser brings back the same saved bank seed rather than rolling a fresh one. Useful to me in two ways:

  1. Could you attach that file? It is ~/.local/share/Rack2/presets/forsitan/imber/template.vcvm, a small JSON. It pins the exact bank your machine builds on every add, so I can regenerate the identical 192 buffers here and either implicate the material or rule it out.
  2. Could you also try moving it aside, mv ~/.local/share/Rack2/presets/forsitan/imber/template.vcvm /tmp/, restart Rack, and add imber again? If the crash goes with it, that narrows things sharply. If it crashes exactly as before, the preset is exonerated and I stop looking there.

And the important one: please start Rack from a terminal and post whatever the terminal prints when it dies. I think the message never reaches log.txt, which is why the log stops mid-line with nothing after it. What I expect to see is a single line like terminate called after throwing an instance of ‘std::bad_alloc’ or std::system_error instead. That line names the exact failure, and it is the one piece of evidence none of us has looked at yet.

@nolente All good here, both Mac & Win.

Okay your requests bring up a couple of points:

  1. I created that template on the off chance that it would solve anything. It didn’t, and I deleted it shortly after. That file no longer exists, but imber still crashes.
  2. HOWEVER, when I run VCVRack in terminal, imber no longer crashes. I can load it over and over, reseed the players over and over, by hand or by cv trigger, and it works fine. Load time on initialization is maybe 1 second. So there is nothing to print.
    1. Additionally, navigating to the Rack executable in my file explorer and double-clicking it, I can load imber without problem.
    2. But clicking on the taskbar icon (a file I created, VCVRack.desktop) and starting VCVRack that way, imber can’t load. ??? I thought the taskbar icon was the same as double-clicking the executable; this is the first time I’ve ever seen a difference between them.

Here is the text of VCVRack.desktop:


[Desktop Entry]
Type=Application
Terminal=false
Name=VCVRack
Path=/home/jakulley/.local/share/VCV/Rack2Pro
Exec=Rack
Icon=/home/jakulley/.local/share/VCV/Rack2Pro/res/icon.png

@jakulley Thank you for the patience, and for trying things that must have felt like they were going nowhere. That last post narrows it a lot.

The only thing that changes now is how the process is started, which points towards the environment it comes up in.

My hypothesis: a process started from a terminal and one started from a .desktop launcher can end up with different resource limits. If that is what is happening here, the ulimit output you posted would be your shell’s limits rather than Rack’s, which would explain why it never lined up with any explanation. imber asks for about 50 MB and one thread when it builds a bank, so a limit that is generous in the one case and tight in the other would decide whether it gets them.

In the meantime you have a workaround: start Rack from a terminal, or by double-clicking the executable. Now that you are not stuck: are you still willing to do a bit more troubleshooting? No hard feelings if not. If yes, two things.

1. The limits Rack actually runs under. Start it from the icon, the way that crashes, and while it is running:

pid=$(pgrep -x Rack)
cat /proc/$pid/limits

If a number is small there where your shell says it is large, that is the answer.

2. The message it prints when it dies. It does print one, but only to the terminal it does not have when it is launched from the icon. Give it somewhere to write instead: edit VCVRack.desktop and change the Exec line to

Exec=bash -c '/home/jakulley/.local/share/VCV/Rack2Pro/Rack 2>&1 | tee /tmp/rack-out.txt'

leaving everything else as it is. Then launch from the icon as usual, add imber, let it die, and post /tmp/rack-out.txt. I expect a single line naming the exact failure, and it is the one thing we have not seen yet.

Two more fixes are brewing here thanks to you, not published yet. If we catch this one too, I can release the lot knowing the problem is actually solved rather than guessed at.

The change to VCVRack.desktop caused it to create /tmp/rack-out.txt, but the file is blank, no text. I tried it several times with the same result.

That screenshot may well have it, second line from the bottom:

Max realtime timeout      200000    200000    us

A thread at realtime priority may burn 200 ms of CPU without blocking, and the kernel enforces that with SIGXCPU, which kills the process silently. imber builds its bank on a thread started from the audio thread, so it inherits realtime priority, and the bank takes around 390 ms on my pc. That would fit: no message anywhere, and a log that stops mid-line.

The count restarts every time the thread blocks, so the render now sleeps for a microsecond between buffers. That leaves about 2 ms of realtime CPU against the 200 ms allowance, whatever priority the thread ends up at, and costs nothing measurable: a bank still takes the same time it always did.

2.13.3 is up if you want to try it: Release Release v2.13.3 · gosub/forsitan-modulare · GitHub

If it still crashes, one more thing would settle it. Change the Exec line to:

Exec=bash -c '/home/jakulley/.local/share/VCV/Rack2Pro/Rack > /tmp/rack-out.txt 2>&1; echo "exit: $?" >> /tmp/rack-out.txt'

and post the last line. exit: 152 is SIGXCPU.

That’s done it! Thanks for taking all the time to figure that out!