Phantom modules haunting my Rack - what is my plugin doing wrong?

I’m having a hard time figuring out this issue with one of my plugins:

After deleting the module from the patch (click, press delete), I get this in the log at the next periodic settings autosave:

[186.538 info src/patch.cpp:225 saveAutosave] Saving autosave G:/repos/Rack/autosave/patch.json
[186.545 warn src/app/RackWidget.cpp:258 mergeJson] Cannot find ModuleWidget 8531809083867533

What’s really bad is that when I close Rack and restart it, that module is reloaded even though it was deleted from the patch. I’ve seen sometimes multiple copies reloaded, and sometimes at off-screen places, so hard to see that it’s happened.

This is obviously a huge problem for users.

Clearly, this plugin/module is doing something wrong – something Rack doesn’t expect, but what?

  • Has anyone else seen this phenomenon (ghost modules returning on reload)?
  • Anyone have an idea what I’m doing wrong that would cause this?
  • Anyone have ideas what part of the Rack code I should be looking in to debug this?

Any help appreciated. Of course, I’ll eventually beg VCV for help.

Module is pachde HC-1

I did have a very brief look at your code, but it is quite complex compared to my project structure so would need to dedicate some time to understand it before I could be useful.

Just off the top of my head though “module_broker” sure seems like something that might be related…

During my day job software engineering, at least 50% of the time I have a unknown problem, I find that just the process of trying to explain how something works to someone else, elucidates the point.

Try writing a bullet point list that explains how the module works during the process of adding it to a patch, some function, and removing it from the patch.

Hopefully as you do this the issue will make itself known.

On the debugging side of things, I would probably start by adding a big DEBUG to the constructor of both the module and the widget.

It is my understanding that each module in the patch gets an ID (which you can maybe access via a param? VCV Rack API: rack::engine::ParamHandle Struct Reference )

edit: you can get the id using rack::engine::Module::getId() VCV Rack API: rack::engine::Module Struct Reference

this could be of use perhaps?

v2 changelog says:

- Add `Engine::getNumModules()` and `Engine::getModuleIds()`.

or maybe this bit of code is helpful?

Sorry, thats all I’ve got for now

1 Like

Thanks so much for taking a peek and giving some hints on where to look in Rack. – it is complex.

However the bug turns out to be a bone-headed mistake. Completely unrelated to the complex inter-module communication this plugin does.

While taking another look based on your hints, while stepping through rack, something clicked, and I looked at my ModuleWidget destructor, and sure enough, for some stupid reason I can’t recall I was assigning module to null. Doh!

If you do that, the base ModuleWidget destructor doesn’t remove the module from Rack’s internal list, and thus orphans the module. And anytime you add another of this module you thereby create another orphan. Rack remembers every module you’ve orphaned to punish you (:-)).

It would all have been just fine if I had called setModule(nullptr) instead of a simple assignment.

Thank you so much for helping me find this. It was driving me crazy.

2 Likes

I think that I’m up to 3 or 4 beers I owe you, now.

2 Likes

Awesome, glad you have fixed it, and just in case it is ever relevant, I’m partial to a juicy neipa :beer:

1 Like