VCV Rack has crashed on module browser

For a while now, more often than not when I try to add a module to my patch, I get the error "VCV Rack has crashed. See /Rack/log.txt " . Attached is a copy of the crash log. How do I tell which plugin/module is causing the crash? Could it be me that is causing the crash due to my Meander module that is still under development? This may or may not be a development forum topic. Interesting, my Meander patch keeps right on playing after the crash.

log.txt (36.2 KB)

Yes, the stack crashes in ZN13MeanderWidget4stepEv, which is the C++ mangled name of MeanderWidget::step.

just so you know, there is also a VCV Rack discord, which has a development channel that may also be of some help.

Now that I’m able to understand the log, I was able to quickly narrow down the line of code that is causing the error. But, it is not clear why the error occurs. As you mentioned, the crash is occurring in MeanderWidget.step(). The line in question is attempting to modily the box component of a button control param. I have some of the controls in an array and I update them in step() and then the changes are rendered in draw(). Is there any reason that this should crash? This probably goes back to my questions last week regarding what should be done in step() and draw(). Note, the crash occurs during the param component read, not write.

Vec start_position=Vec(0,0);        
Vec buttonPosition=start_position.plus(Vec(0, (i*verticalIncrement)));
DEBUG("void MeanderWidget.step()-3.0.3"); 
buttonPosition.y -= CircleOf5thsSelectStepButton[i]->box.size.y;  // adjust for box height
DEBUG("void MeanderWidget.step()-3.0.4"); 
CircleOf5thsSelectStepButton[i]->box.pos=buttonPosition;

The last logged line before the crash is void MeanderWidget.step()-3.0.3 . Does this have something with the module manager trying to read and render the panel image at the same time the running module is trying to do the same?

Impossible to say without knowing the rest of the source. Is i a valid index?

Yes, I’ve checked the array indices and even checked it back to the parameter creation code array indices.

I could certainly be wrong, but I think this crash is somehow related to the module manager and my executing module conflicting. The line in question is executed many times without problem until I try to add a module. Just displaying the available modules crashes. I don’t have to select a new module to add.

it might be worthwhile to check to see if you have something like this in your module widget:

module->databind = somevalue;

or:

somevalue = module->databind;

in which case you need to fence it with a check for module:

if (module) {
...
}

as the module browser instantiates the widget without instantiating the module itself.

Anywhere I have a module-> pointer, I have that surrounded by if (module) {}; My draw functions also the first line as if (module==NULL) return. Of course the module pointer gets assigned to other pointer objects and I may not be checking all of those for null.

Can the module suddenly become invalid?

What happens in the module browser? Does the browser load some instance of the module in order to get the populated panel image, as opposed to just the SVG panel image?

It appears that the module browser is what is crashing since my actual module keeps executing in the background, but I may be misunderstanding. But the log seems to show that at least the MeanderWidget.step() function is no longer functioning after the crash. Confusing.

technically? yes :slight_smile: but in practice likely not. unless you have code somewhere mutating it, it would be one of those cosmic rays shift a bit in ram type of events, not something rack is doing behind your back.

maybe open it up in gdb? since you’re in windows, it might be worth taking a quick read of Msys2 gdb workaround

The module browser instantiates a moduleWidget, but it does not instantiate a Module to go with it. If scrolling the browser down to your module is enough to crash rack, the problem is almost certainly that your widget is trying to refer to the module or something in the module.

1 Like

That makes perfect sense! Now to figure out what I’m doing wrong.

void MeanderWidget::step() override {

// Read param component values created in MeanderWidget() constructor

Widget::step()
};

I can make the problem go away the above by commenting out the param component read.

Thanks for explaining this.

OT, and maybe you have a good reason for doing this way, but shouldn’t you call ModuleWiget::step() in place of Widget::step()

Blockquote OT, and maybe you have a good reason for doing this way, but shouldn’t you call ModuleWiget::step() in place of Widget::step()

I just now tried that but the module crashes on launch, with nothing but white screen displayed for a few seconds.

Sorry about that. I misread and called MeanderWidget::step(). When I replaced that with Widget::step(), the module launches runs properly, but the crash in the module browser still occurs.

Don’t just look at the step() method in your ModuleWidget, look also at the constructor and any child widget that you would add to your main widget with addChild() , if any of them access to a NULL module pointer, that would cause a crash in the browser.

Yeah, that’s exactly what is happening. When the browser MeanderWidget instantiation occurs, the module is null. As @jerrysv suggested yesterday, I need to check for the module being non-null in every possible usage.

What is the standard methodology for handling this browser instantiated widget? Do I need to surround everything in the constructor with “if (module() {}”? Or is there some processing that has to occur in the constructor to handle the browser instantiated widget without a module?

Getting close!

No, just apply it when a module’s member is called. Do you have custom widgets you add in the constructor ? If so be sure to check their code as well. Also what I usually do when I need data for display, is to provide a default value if the module is NULL ex :

if(module) {
    value = module->value;
}
else {
    value = 1;
}

When needed to be sure the browser thumbnail is somewhat “realistic”

I added the module check to MeanderWidget::step() and that prevented the browser crash. I need to analyze the rest of my code to see if there are other places that need this check.

I did add the module check into 3 other draw() functions.

Thanks for your help, as well as thank you @jerrysv for your help. I just was not thinking in terms of there being multiple instances of a widget or without a module. I’m a bit slow; I guess that is why you all were mentioning headless mode for v2.

My celebration was a bit premature. The step() function was not crashing because my if (module) check was checking a local step() declared but uninitialized module variable, so the step() logic was not executed. When I corrected this to use the widget module, the crash returned.

Just to clarify, step() should work fine if the MeanderWidget module is checked and is non-null, right. I’m thinking that most likely the crash is originating in the MeanderWidget() constructor where I am creating params, even if the module is null. Does that make sense?