Stack overflow without actual infinite loop: possible?

Tom Swirly's icon

I have a complex patch which I broke up in an interesting and perhaps-too-clever but extremely systematic way; but in doing so I now get a Stack Overflow error whenever I run it.

My logic didn't change, so this surprised me (well, actually I'm more surprised when things work but...)

However, my further investigations with the debugger were very puzzling.

There *is* deliberately a "feedback loop"; where the output of one box is (transitively) connected to one of its inputs and an output might generate another input.

HOWEVER, there is no possibility of an infinite loop.

There wasn't one in the previous logic.

I run through it in the debugger; everything is going smoothly, it's gone several times through the "feedback" section with different values, it's actually about to route the last message, and then it quite suddenly announces a stack overflow in a sprintf on the 51 step. (stack depth = 50?)

I removed the feedback segment, simply printing out the values that it emitted, and then pasting those messages into a message box which I then put into the inlet - "message passing by hand".

I see exactly the messages I used to see going through the system; no more and no less.

1. Is there some possibility for the "stack overflow" just because I'm doing a lot of sends?

Can I simply somehow crank my stack to be huge and not worry about it, given that I'll always be able to prove that each cascade of messages is finite (and fairly short, I guess I'm surprised it overflowed)?

I didn't find any place to change the stack depth, though.

2. Is there some technical document on how "the stack" and "send" works?

When I use a feature, I make heavy use of it (I believe the golden hammer theory works really well if you have enough different hammers :-D) so I'd love to know any limitations before shooting myself in the boxes-and-wires.

3. Let me tell you about my (too-)clever trick - perhaps that's it.

I had a complex patch with a number of visually small medium-complex objects, each of which were communicating with many others through many wires.

I now send all messages to a central router, that re-sends them to the parts.

Example: before I had a wires going from parts of the pattrstorage output processor to places in my "selector", "hinter", "last patch name box", "last patch number box".

Now I simply have message boxes like

; #1 hinter hint $2 $1

(see also Note 1 below)

Now, so far this is great - but here's the part I think overly complex and am going to rip out while I wait for an answer from you:

In a central spot I have

(r #1) --> (sf #1)

where sf is a box that "does subrouting":

(message hello world) -> (sf why)

sends the message "world" to "why-hello".

(I also have a box called r2, where (r2 x y) is exactly the same as r x-y: this is so I can say (r2 #1 y))

why am I doing this? well, I guess I didn't want every recipient of this to have to filter the messages, I wanted "send" to do it, but this way I have to construct a string each time, so it's hardly better.

And it's all encapsulated so I can get rid of this part and nothing else will change.

I'll let you know how it works. Meanwhile, any authoritative information on how the stack, send, that sort of thing work would be extremely interesting....

(Note 1 - there's an entertaining bug where for some reason, message boxes with contents like this believe they have an invisible trailing carriage return and so always have an extra, blank or near-blank line on the screen! try it yourself, past that text into a message box....)

Tom Swirly's icon

Encapsulation is a marvellous thing. :-D It took me a minute to do it.

So that little change did it and the thing works like a charm (modulo some bugs in the new functionality).

Now we know the answer in the back of the book, what was I doing wrong?