BelaPlatform / supercollider

an environment and programming language for real time audio synthesis and algorithmic composition
GNU General Public License v3.0
14 stars 8 forks source link

Scope occasionally causes segfault #80

Closed giuliomoro closed 3 years ago

giuliomoro commented 3 years ago

I am manually starting scsynth on the board (scsynth -u 57110 -z 16 -J 8 -K 8 -G 16 -i 2 -o 2 -B 0.0.0.0 -O 4) and then using the Sc (3.11.1) IDE on my computer (after updating the relevant class files) to communicate with the board. Occasionally, when I start a synthdef which includes the .belaScope(), I get a segmentation fault on the server. IIRC, when running scsynth inside gdb, it tells me the segfault is happening inside Bela's Scope::triggered() at the line

                float cur = buffer[channelWidth * triggerChannel + readPointer];

when triggerChannel == 0 and readPointer == 0 and buffer seems to be valid and ~20k elements long, so I am not sure why that would segfault.

This may well be Bela's Scope code's fault, some hidden bug that only is revealed in this circumstance. @elgiano could you please explain to me at a high level how the .belaScope() magic works? This way I can get a better sense of what to look out for while trying to debug this.

elgiano commented 3 years ago

Sure, let me know if this is enough:

If you try to create more than one BelaScopeUGen on the same server, the exceeding ones will do nothing. I'm working on a PR to raise the Done flag in this case, so that BelaScope (on sclang) can notice and free that superfluous synth, and eventually hook to an already existing one.

Please feel free to ask me more specific questions if you need, and we can also try to find time to look at this together if you would like

giuliomoro commented 3 years ago

that's a good start, could you say something more about the logic of the sclang side of things? When is the BelaScopeUGen created?

If you try to create more than one BelaScopeUGen on the same server,

how does one do that?

I'm working on a PR to raise the Done flag in this case, so that BelaScope (on sclang) can notice and free that superfluous synth, and eventually hook to an already existing one.

That would be welcome. I think had sometimes the situation where the scope would stop working even if I had just done s.freeAll and instantiated a new synth. Or possibly if I was restarting the server? I guess I ended up doing always rebooting the interpreter after restarting the server.

elgiano commented 3 years ago

how does one do that?

Everytime one creates a synth that contains BelaScopeUGen, like { BelaScopeUGen.ar() }.play

When is the BelaScopeUGen created?

You can initialize BelaScope (sclang) for a server by manually by doing BelaScope(s). At this point (or when the server will start, if it's not running already) a synth containing BelaScopeUGen is created. Also, if you call .belaScope() or other scoping methods without initializing BelaScope manually, it will be initialized automatically for you.

I hope this answers your question :)

I don't think this is related to OP, but problems appear when different entities try to scope, for example when you start scoping from some code on the Bela Web UI, and then again from a "remote" sclang, or even across sclang reboots when the server persists them, or across scsynth reboots when sclang persists. In all these cases, there is at least one entity that doesn't have control over the BelaScopeUGen that already exists (or that controls a BelaScopeUGen that doesn't exist anymore, although this just leads to the creation of a new one and shouldn't be a problem). I'm working on it

elgiano commented 3 years ago

I made a working draft at #81. Maybe @giuliomoro you would like to try it and also see if your crashes persist? Thanks!

giuliomoro commented 3 years ago

didn't see this happen again