Bugs item #1518030, was opened at 2006-07-06 11:54 Message generated for change (Comment added) made by sistisette You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=478070&aid=1518030...
Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: puredata Group: v0.40.1 Status: Open Resolution: None Priority: 7 Private: No Submitted By: ClaudiusMaximus (claudiusmaximus) Assigned to: Miller Puckette (millerpuckette) Summary: subpatch clearing itself crashes Pd
Initial Comment: Tested on Linux with pd-0.39-2 from Miller's site.
Steps to reproduce:
start pd load the patch attached to this post click the bng close the patch load the patch again click the bng => crash
OR
start pd load the patch open the subpatch (optionally: close the subpatch) click the bng => crash
Here's a gdb backtrace:
Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 16384 (LWP 27794)] pd_bang (x=0x11) at m_pd.c:269 269 m_pd.c: No such file or directory. in m_pd.c (gdb) where #0 pd_bang (x=0x11) at m_pd.c:269 #1 0x0808a61b in outlet_bang (x=0x3) at m_obj.c:328 #2 0x080765ad in bng_bout2 (x=0x81f2790) at g_bang.c:294 #3 0x080767f6 in bng_newclick (z=0x11, glist=0x81f2338, xpix=74, ypix=70, shift=0, alt=0, dbl=0, doit=1) at g_bang.c:343 #4 0x0806e907 in gobj_click (x=0x0, glist=0x11, xpix=17, ypix=17, shift=17, alt=17, dbl=17, doit=17) at g_editor.c:92 #5 0x0805b557 in graph_click (z=0x81f2338, glist=0x11, xpix=74, ypix=70, shift=0, alt=0, dbl=17, doit=1) at g_graph.c:1059 #6 0x0806e907 in gobj_click (x=0x0, glist=0x11, xpix=17, ypix=17, shift=17, alt=17, dbl=17, doit=17) at g_editor.c:92 #7 0x08070a97 in canvas_doclick (x=0x81ecd08, xpos=74, ypos=70, which=1, mod=0, doit=1) at g_editor.c:1094 #8 0x0807119d in canvas_mousedown (x=0x11, xpos=0, ypos=0, which=0, mod=0) at g_editor.c:1252 #9 0x08089789 in pd_typedmess (x=0x81ecd08, s=0x0, argc=0, argv=0x80cf488) at m_class.c:728 #10 0x08089665 in pd_typedmess (x=0x81f25f8, s=0x0, argc=4, argv=0x80cf468) at m_class.c:749 #11 0x0808c32f in binbuf_eval (x=0x11, target=0x81f25f8, argc=0, argv=0x0) at m_binbuf.c:574 #12 0x08091fdf in socketreceiver_read (x=0x81ec2f0, fd=7) at s_inter.c:540 #13 0x0809180f in sys_domicrosleep (microsec=17, pollem=1) at s_inter.c:180 #14 0x08092660 in sys_pollgui () at s_inter.c:823 #15 0x0808fe5b in m_scheduler () at m_sched.c:466 #16 0x08095b1b in main (argc=17, argv=0x11) at s_entry.c:27
----------------------------------------------------------------------
Comment By: Matteo Sisti Sette (sistisette) Date: 2007-02-10 19:45
Message: Logged In: YES user_id=1709568 Originator: NO
Just another example that triggers the same bug (dunnow why I can't attach a file so I "transcribe" it here):
[bng] | [f 0] | [find f, cut( | [s pd-thisFile'sName.pd]
I don't agree with zmoelnig in that it is not a bug. Calling functions and stacks are implementation details the patch author shouldn't need to be aware of. What the patch is doing is deleting an object. The message causing the deletion was triggered by (a message that was triggered by[...]) that object, so what? There's nothing semantically incorrect in doing that.
----------------------------------------------------------------------
Comment By: ClaudiusMaximus (claudiusmaximus) Date: 2006-10-18 18:30
Message: Logged In: YES user_id=769033
Some comments about pd-0.40-1 from Miller's site:
1. Start pd, load gop-subpatch-self-clear-crash.pd, click bang => no crash, subpatch is cleared correctly
2. Start pd, load gop-subpatch-self-clear-crash.pd, open subpatch, click bang => crash:
Program received signal SIGSEGV, Segmentation fault. [Switching to Thread -1211095376 (LWP 13534)] pd_bang (x=0x11) at m_pd.c:269 269 (*(*x)->c_bangmethod)(x); (gdb) bt #0 pd_bang (x=0x11) at m_pd.c:269 #1 0x080aa8eb in outlet_bang (x=0x82371f8) at m_obj.c:328 #2 0x0808f101 in bng_newclick (z=0x82415c8, glist=0x8241200, xpix=136, ypix=139, shift=0, alt=0, dbl=0, doit=1) at g_bang.c:294 #3 0x0808a36a in canvas_doclick (x=0x8241200, xpos=136, ypos=139, which=1, mod=0, doit=1) at g_editor.c:92 #4 0x0808b14b in canvas_mousedown (x=0x8241200, xpos=136, ypos=139, which=1, mod=0) at g_editor.c:1242 #5 0x080a79c5 in pd_typedmess (x=0x8241200, s=0x822ac40, argc=4, argv=0x811a928) at m_class.c:728 #6 0x080a7632 in pd_typedmess (x=0x8241418, s=0x822ac40, argc=<value optimized out>, argv=0x811a928) at m_class.c:749 #7 0x080abba4 in binbuf_eval (x=0x82366e0, target=<value optimized out>, argc=0, argv=0x0) at m_binbuf.c:673 #8 0x080b94be in socketreceiver_read (x=0x8236700, fd=8) at s_inter.c:540 #9 0x080b693e in sys_domicrosleep (microsec=<value optimized out>, pollem=<value optimized out>) at s_inter.c:180 #10 0x080b7967 in sys_pollgui () at s_inter.c:825 #11 0x080b2f53 in m_scheduler () at m_sched.c:466 #12 0x080b651a in sys_main (argc=1, argv=0xbfcbb4a4) at s_main.c:316 #13 0x080bf7cf in main (argc=136563232, argv=0x8242b00) at s_entry.c:27
3. Start pd, load gop-subpatch-self-clear-crash.pd, open subpatch, close subpatch, click bang => crash
Program received signal SIGSEGV, Segmentation fault. [Switching to Thread -1210849616 (LWP 13563)] pd_bang (x=0x11) at m_pd.c:269 269 (*(*x)->c_bangmethod)(x); (gdb) bt #0 pd_bang (x=0x11) at m_pd.c:269 #1 0x080aa8eb in outlet_bang (x=0x82373c0) at m_obj.c:328 #2 0x0808f101 in bng_newclick (z=0x823cbc0, glist=0x8237230, xpix=72, ypix=70, shift=0, alt=0, dbl=0, doit=1) at g_bang.c:294 #3 0x0805be1a in graph_click (z=0x8237230, glist=0x8237090, xpix=72, ypix=70, shift=0, alt=0, dbl=0, doit=1) at g_graph.c:1052 #4 0x0808a36a in canvas_doclick (x=0x8237090, xpos=72, ypos=70, which=1, mod=0, doit=1) at g_editor.c:92 #5 0x0808b14b in canvas_mousedown (x=0x8237090, xpos=72, ypos=70, which=1, mod=0) at g_editor.c:1242 #6 0x080a79c5 in pd_typedmess (x=0x8237090, s=0x822ac40, argc=4, argv=0x811a928) at m_class.c:728 #7 0x080a7632 in pd_typedmess (x=0x823ca28, s=0x822ac40, argc=<value optimized out>, argv=0x811a928) at m_class.c:749 #8 0x080abba4 in binbuf_eval (x=0x82366e0, target=<value optimized out>, argc=0, argv=0x0) at m_binbuf.c:673 #9 0x080b94be in socketreceiver_read (x=0x8236700, fd=8) at s_inter.c:540 #10 0x080b693e in sys_domicrosleep (microsec=<value optimized out>, pollem=<value optimized out>) at s_inter.c:180 #11 0x080b7967 in sys_pollgui () at s_inter.c:825 #12 0x080b2f53 in m_scheduler () at m_sched.c:466 #13 0x080b651a in sys_main (argc=1, argv=0xbfeee6d4) at s_main.c:316 #14 0x080bf7cf in main (argc=136541136, argv=0x823e958) at s_entry.c:27
4. Start pd, load crash-1518030.pd, click "bang" => crash:
Program received signal SIGSEGV, Segmentation fault. [Switching to Thread -1210677584 (LWP 13575)] pd_bang (x=0x11) at m_pd.c:269 269 (*(*x)->c_bangmethod)(x); (gdb) bt #0 pd_bang (x=0x11) at m_pd.c:269 #1 0x080aa8eb in outlet_bang (x=0x8237408) at m_obj.c:328 #2 0x080aa8eb in outlet_bang (x=0x82373d0) at m_obj.c:328 #3 0x080aa8eb in outlet_bang (x=0x823cce0) at m_obj.c:328 #4 0x080a77a1 in pd_typedmess (x=0x823cccc, s=0x8119364, argc=0, argv=0x811a950) at m_class.c:641 #5 0x080abba4 in binbuf_eval (x=0x823cc68, target=<value optimized out>, argc=1, argv=0xbfa50e8c) at m_binbuf.c:673 #6 0x0805f46d in message_click (x=0x823ccb0, xpos=91, ypos=65, shift=0, ctrl=0, alt=0) at g_text.c:300 #7 0x08063721 in text_click (z=0x823ccb0, glist=0x8237080, xpix=91, ypix=65, shift=0, alt=0, dbl=0, doit=1) at g_text.c:1065 #8 0x0808a36a in canvas_doclick (x=0x8237080, xpos=91, ypos=65, which=1, mod=0, doit=1) at g_editor.c:92 #9 0x0808b14b in canvas_mousedown (x=0x8237080, xpos=91, ypos=65, which=1, mod=0) at g_editor.c:1242 #10 0x080a79c5 in pd_typedmess (x=0x8237080, s=0x822ac40, argc=4, argv=0x811a928) at m_class.c:728 #11 0x080a7632 in pd_typedmess (x=0x823ca28, s=0x822ac40, argc=<value optimized out>, argv=0x811a928) at m_class.c:749 #12 0x080abba4 in binbuf_eval (x=0x82366e0, target=<value optimized out>, argc=0, argv=0x0) at m_binbuf.c:673 #13 0x080b94be in socketreceiver_read (x=0x8236700, fd=8) at s_inter.c:540 #14 0x080b693e in sys_domicrosleep (microsec=<value optimized out>, pollem=<value optimized out>) at s_inter.c:180 #15 0x080b7967 in sys_pollgui () at s_inter.c:825 #16 0x080b2f53 in m_scheduler () at m_sched.c:466 #17 0x080b651a in sys_main (argc=1, argv=0xbfa52a44) at s_main.c:316 #18 0x080bf7cf in main (argc=0, argv=0x0) at s_entry.c:27
----------------------------------------------------------------------
Comment By: IOhannes m zmölnig (zmoelnig) Date: 2006-10-10 17:13
Message: Logged In: YES user_id=564396
the really interesting thing here, is that your patch will not crash when you only click on the [bng] once. you have to follow the steps as described.
i add another patch that triggers the crash reliable and without the complicated procedure (just click it and crash it)
raised priority, since crashers should be fixed.
----------------------------------------------------------------------
Comment By: IOhannes m zmölnig (zmoelnig) Date: 2006-07-06 20:48
Message: Logged In: YES user_id=564396
this has nothing to do with GOP, therefore i renamed the bug-report.
what happens: an object emits a message; the calling function is pushed to the stack; the message triggers the deletion of the object; after the message is done, the calling function (of the now deleted object) is popped back from the stack: but alas! the entire environment has changed and nothing is as it should be....stack corruption -> crash.
personally i think, that this is NOT a bug in pd but rather a bug in the patch (but i am repeating myself...)
----------------------------------------------------------------------
You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=478070&aid=1518030...
Hallo,
SourceForge.net hat gesagt: // SourceForge.net wrote:
Comment By: Matteo Sisti Sette (sistisette) Date: 2007-02-10 19:45
Message: Logged In: YES user_id=1709568 Originator: NO
Just another example that triggers the same bug (dunnow why I can't attach a file so I "transcribe" it here):
[bng] | [f 0] | [find f, cut( | [s pd-thisFile'sName.pd]
I don't agree with zmoelnig in that it is not a bug. Calling functions and stacks are implementation details the patch author shouldn't need to be aware of. What the patch is doing is deleting an object. The message causing the deletion was triggered by (a message that was triggered by[...]) that object, so what? There's nothing semantically incorrect in doing that.
There is. You may be missing some implications of Pd's "depth first message passing" as described in the manual, chapter "2.3.2. depth first message passing": [1]
"Each message sets off a tree of consequent messages." As a message is generated by an object this also means that each (message) object sets off a tree of messages. Every branch of messages has to finish at some point. If it doesn't, you have an error in your patch, that will result in an infinite message loop or "stack overflow". The manual has an example for this, but you can also just bang an [until] without stopping it to make such a stack overflow without any backwards connections.
Now how does this relate to "suicide" messages, that is, messages that will result in a deletion of the object that generated the message?
Lets look at the [pd x] subpatch which has a [; pd-x clear( suidice message: As soon as you click this message, it will start a "message tree of consequent messages." This message tree has to finish, and the end point here would be the clearing of the subpatch including the message box that initiated the suidice.
At first look this may seem okay, but a powerful and important feature of Pd is, that an object or message can be a node for several message branches. [trigger bang float] is one example for this: Pd will first execute the tree below the right float outlet completely, and when this is finished, it will come back to the [t b f] to work on the left bang outlet's tree. With messages this also is possible, e.g. by seperating messages with a comma or semicolon: [; pd-x clear; pd-x msg 100 100 hello world(: First this message will clear [pd x] then it will evaluate the second part of the message and put a "hello world" message into [pd x].
To be able to do this Pd has to save the current branching node somehow to come back there later, when the first branch has finished.
But now we have a problem, if a message tries to commit suicide and thus deletes the node that according to Pd's language rules and logic needs to be evaluated again, after the "depth first tree" has come to an end!
As the node was deleted, this is impossible, the correct data flow cannot be restored and that's why these messages indeed are semantically incorrect just like infinite message loops. Of course Pd should not die if someone attempts suidide, but still these kinds of messages are illegal constructs.
Ciao
On Sun, 2007-02-11 at 12:42 +0100, Frank Barknecht wrote:
What the patch is doing is deleting an object. The message causing
the
deletion was triggered by (a message that was triggered by[...])
that
object, so what? There's nothing semantically incorrect in doing that.
There is. You may be missing some implications of Pd's "depth first message passing" as described in the manual, chapter "2.3.2. depth first message passing": [1]
i wouldn't say that committing suicide is illegal, just because there is an easy explanation / workaround or the implementation of pd is buggy.
it somehow reminds me of the old jokes beginning with "if cars would be built like software is written" ...
tim
-- tim@klingt.org ICQ: 96771783 http://www.mokabar.tk
The composer makes plans, music laughs. Morton Feldman
Hallo, Tim Blechmann hat gesagt: // Tim Blechmann wrote:
On Sun, 2007-02-11 at 12:42 +0100, Frank Barknecht wrote:
What the patch is doing is deleting an object. The message causing
the
deletion was triggered by (a message that was triggered by[...])
that
object, so what? There's nothing semantically incorrect in doing that.
There is. You may be missing some implications of Pd's "depth first message passing" as described in the manual, chapter "2.3.2. depth first message passing": [1]
i wouldn't say that committing suicide is illegal, just because there is an easy explanation / workaround or the implementation of pd is buggy.
Well, then how should Pd solve the logical pitfalls in your opinion?
I'm not talking about the crash here, which of course is completly "illegal", but what would be your suggestion to what should happen, if something like this was patched:
[t b b] | | ... [s delete-the-t-b-b-above]
Should Pd just delete the trigger if a bang hits it and ignore the trigger's left outlet altogether? Or should Pd rather ignore the bang and issue a warning? The second solution would be what I would prefer, but even that has issues: What should happen to the state of the objects above the trigger:
[bng] | [f 0]x[+ 1] | [select 0] | [t b b] | | ... [s delete-the-trigger-above]
Should the counter be at 1 or should it stay at 0 if the [t b b] commits suicide and execution has to stop?
And what's with going the other way around:
[t b b] | | | [s do-something] | [s delete-the-t-b-b-above]
Should Pd first "do-something" and then, at the same logical time, delete the object that "did-something"?
To me all of this looks like a can of worms. These kinds of suicide constructs in my view are just illogical, wrong and should not be allowed. They don't do anything sensible anyway and if someone really insists on committing suicide, the right way is to insert a [delay] object as mentioned in the manual:
[t b b] | | | [delay] | | ... [s delete-the-trigger-above]
Ciao
Well, then how should Pd solve the logical pitfalls in your opinion?
mark the object as deletable, if the messaging is happening, wait for the object to return from the message function, then it can be safely deleted. implementing it shouldn't be difficult as it is completely compatible with pd's synchronous architecture.
do any logical pitfalls exist in this situation?
tim
-- tim@klingt.org ICQ: 96771783 http://www.mokabar.tk
There's no such entity as "most people". These are generalities. All generalities are meaningless. You've got to pin it down to a specific person doing a specific thing at a specific time and space. William S. Burroughs
Hallo, Tim Blechmann hat gesagt: // Tim Blechmann wrote:
Well, then how should Pd solve the logical pitfalls in your opinion?
mark the object as deletable, if the messaging is happening, wait for the object to return from the message function, then it can be safely deleted. implementing it shouldn't be difficult as it is completely compatible with pd's synchronous architecture.
If I understand it right, what you suggest is similar to adding a [delay] object into the chain to defer the actual killing to a point, when all current operations are complete.
But additionally your proposal would introduce the possibility, that an object disappears, before all other objects have completed the current logical step, too. So the bottom line would be dividing the single logical step we have now into two (or even more) steps, that all need to be executed in the correct order. What's the gain of making execution order more complicated? I guess this is not just to allow sloppily coded suicides.
(I'm a bit worried because a lot of the problems people have with their patches are there, because they didn't get the execution order right. Complicating this area could confuse them even more.)
Ciao
mark the object as deletable, if the messaging is happening, wait
for
the object to return from the message function, then it can be
safely
deleted. implementing it shouldn't be difficult as it is completely
compatible
with pd's synchronous architecture.
If I understand it right, what you suggest is similar to adg a [delay] object into the chain to defer the actual killing to a point, when all current operations are complete.
or the other way round ... you use the delay object to achieve, that the object is deleted after the messages have occurred ... :P
But additionally your proposal would introduce the possibility, that an object disappears, before all other objects have completed the current logical step, too. So the bottom line would be dividing the single logical step we have now into two (or even more) steps, that all need to be executed in the correct order. What's the gain of making execution order more complicated? I guess this is not just to allow sloppily coded suicides.
i'm not splitting the logical step, i just change the interpreter state in a totally predictable way.
but don't worry, i'll leave the implementation of this to a pd developer ...
tim
-- tim@klingt.org ICQ: 96771783 http://www.mokabar.tk
There's no such entity as "most people". These are generalities. All generalities are meaningless. You've got to pin it down to a specific person doing a specific thing at a specific time and space. William S. Burroughs
Hallo, Tim Blechmann hat gesagt: // Tim Blechmann wrote:
i'm not splitting the logical step, i just change the interpreter state in a totally predictable way.
I don't know Pd's internals nearly as good as you, but still it seems to me, that suicides in the middle of a logical step have pitfalls. As Thomas wrote, a suicidal object should not generate further messages. However this suicidal object may already have scheduled further messages. What happens to other branches after the suicidal object, e.g.:
[r y] | [symbol x] | [t a b] | | | [s kill-symbol-x] | [s y]
Should execution go on to the [s y]? Again with an inserted explicit [delay] it is much easier to follow the logic flow and understand what's going on (and what's maybe going wrong).
Ciao
On Sun, 2007-02-11 at 23:27 +0100, Frank Barknecht wrote:
Hallo, Tim Blechmann hat gesagt: // Tim Blechmann wrote:
i'm not splitting the logical step, i just change the interpreter state in a totally predictable way.
I don't know Pd's internals nearly as good as you, but still it seems to me, that suicides in the middle of a logical step have pitfalls. As Thomas wrote, a suicidal object should not generate further messages. However this suicidal object may already have scheduled further messages. What happens to other branches after the suicidal object, e.g.:
[r y] |
[symbol x] | [t a b] | | | [s kill-symbol-x] | [s y]
i don't see a problem with the following signal flow (indentation represents the message stack):
symbol x, execute outlet 1 t a b, execute outlet 2 s kill-symbol-x, mark 'symbol x' deletable t a b, execute outlet 1 s y, send r y, receive symbol x, set object symbol x, returning from outlet 1, as it's marked as deletable, remove it from the interpreter
tim
-- tim@klingt.org ICQ: 96771783 http://www.mokabar.tk
Most of the trouble in this world has been caused by folks who can't mind their own business, because they have no business of their own to mind, any more than a smallpox virus has. William S. Burroughs
Hallo, Tim Blechmann hat gesagt: // Tim Blechmann wrote:
On Sun, 2007-02-11 at 23:27 +0100, Frank Barknecht wrote:
[r y] |
[symbol x] | [t a b] | | | [s kill-symbol-x] | [s y]
i don't see a problem with the following signal flow (indentation represents the message stack):
symbol x, execute outlet 1 t a b, execute outlet 2 s kill-symbol-x, mark 'symbol x' deletable t a b, execute outlet 1 s y, send r y, receive symbol x, set object symbol x, returning from outlet 1, as it's marked as deletable, remove it from the interpreter
I probably misunderstood you: I thought, that as soon as the [symbol x] object was killed the reason to fire the "anything" outlet of the trigger was gone as well, so this outlet should *not* be allowed to fire.
But as I understand it now, your proposal is exactly the same as the current [delay] solution, just one object less (the [delay]), one crash less and still no "micro steps". [symbol x] would live until the end of the logical step and be killed afterwards.
I still prefer the explicitness of [delay], though.
Ciao
I probably misunderstood you: I thought, that as soon as the [symbol x] object was killed the reason to fire the "anything" outlet of the trigger was gone as well, so this outlet should *not* be allowed to fire.
if the pd language would have a notion of exceptions, this would make sense, but otherwise this would contradict with the pd language, wouldn't it?
But as I understand it now, your proposal is exactly the same as the current [delay] solution, just one object less (the [delay]), one crash less and still no "micro steps". [symbol x] would live until the end of the logical step and be killed afterwards.
of course, several of these structures could be nested like:
| |t b b| | | | |pd suicide| | |pd suicide2|
providing several interpreter states at the same logical time.
I still prefer the explicitness of [delay], though.
which of course only provides one interpreter state per logical time, but of course, it's a workaround, that should work fine ...
t
-- tim@klingt.org ICQ: 96771783 http://www.mokabar.tk
Desperation is the raw material of drastic change. Only those who can leave behind everything they have ever believed in can hope to escape. William S. Burroughs
Am 11.02.2007 um 21:50 schrieb Tim Blechmann:
Well, then how should Pd solve the logical pitfalls in your opinion?
mark the object as deletable, if the messaging is happening, wait for the object to return from the message function, then it can be safely deleted.
exactly, but the object should not process any further messages when the mark is set. I recently encountered the same situation, and by debugging i found that the crash happens while traversing the outlets to see if the message should be sent to other objects. It would be easy to check for such a mark there.
greetings, Thomas
Hallo, Thomas Grill hat gesagt: // Thomas Grill wrote:
Am 11.02.2007 um 21:50 schrieb Tim Blechmann:
Well, then how should Pd solve the logical pitfalls in your opinion?
mark the object as deletable, if the messaging is happening, wait for the object to return from the message function, then it can be safely deleted.
exactly, but the object should not process any further messages when the mark is set. I recently encountered the same situation, and by debugging i found that the crash happens while traversing the outlets to see if the message should be sent to other objects. It would be easy to check for such a mark there.
I'm wondering: There are other, less obvious cases of suicide that currently lead to a crash. I encountered this when trying to close the Gem-window by watching for the <Esc> key with [gemkeyname] connected to [0, destroy(--[gemwin]. This also crashes Pd and according to IOhannes for a similar reason. Inserting a [delay] in between this will fix it as well. However here not a single object is deleted. Which object should be "marked" here?
Ciao
Frank Barknecht wrote:
Hallo, Thomas Grill hat gesagt: // Thomas Grill wrote:
Am 11.02.2007 um 21:50 schrieb Tim Blechmann:
Well, then how should Pd solve the logical pitfalls in your opinion?
mark the object as deletable, if the messaging is happening, wait for the object to return from the message function, then it can be safely deleted.
exactly, but the object should not process any further messages when the mark is set. I recently encountered the same situation, and by debugging i found that the crash happens while traversing the outlets to see if the message should be sent to other objects. It would be easy to check for such a mark there.
I'm wondering: There are other, less obvious cases of suicide that currently lead to a crash. I encountered this when trying to close the Gem-window by watching for the <Esc> key with [gemkeyname] connected to [0, destroy(--[gemwin]. This also crashes Pd and according to IOhannes for a similar reason. Inserting a [delay] in between this will fix it as well. However here not a single object is deleted. Which object should be "marked" here?
btw, this has been fixed in Gem some time ago (at least it should!) the way it is done, is by entering a "deletable" state, which will be executed asap (but after stack execution), which is basically after a [del 0] (sounds familiar...)
i am not totally happy with this solution because of the following problem: [destroy, create( what should happen here? (well the answer is trivial; but it is not so trivial any more, if we depend on execution order) 2 solutions come to my mind: - since [destroy( is delayed, [create( has to be delayed too; this would lead us to hell... - since the window is still existing when we call [create(, no new window is created (but the destruction is canceled); this is NOT what we have told the interpreter to do; destroying and re-creating a context is NOT the same as not touching it at all.
i think the problem is not a big one, if we consider only the single case of destroying the Gem-window. (this could always be seen as a "special" case)
however, i don't think it is a valid assumption for pd itself. in this case, i would highly prefer an error-message to the console (an "exception") and no destruction at all. (since usually you have more complex settings when doing dynamic patching, e.g. [clear, obj 0 0 inlet, obj 0 100 outlet, connect 0 0 1 0( )
i think i have said this already, the last time this issue came up.
mfg.asd IOhannes
Hallo, IOhannes m zmoelnig hat gesagt: // IOhannes m zmoelnig wrote:
btw, this has been fixed in Gem some time ago (at least it should!)
I admit that I didn't check. (Actually I can't check, as currently for me every "destroy" crashes Pd.)
however, i don't think it is a valid assumption for pd itself. in this case, i would highly prefer an error-message to the console (an "exception") and no destruction at all. (since usually you have more complex settings when doing dynamic patching, e.g. [clear, obj 0 0 inlet, obj 0 100 outlet, connect 0 0 1 0( )
"clear" alone may be fine in this case, but I suppose things get hairy if you just delete a some objects using e.g. "find foo, cut", and then create some new ones and try to connect them. Wouldn't the numbering of objects necessary for [connect ...( be invalid now, too? At least the bookkeeping would get even more difficult than it already is.
Ciao
Frank Barknecht wrote:
however, i don't think it is a valid assumption for pd itself. in this case, i would highly prefer an error-message to the console (an "exception") and no destruction at all. (since usually you have more complex settings when doing dynamic patching, e.g. [clear, obj 0 0 inlet, obj 0 100 outlet, connect 0 0 1 0( )
"clear" alone may be fine in this case, but I suppose things get hairy
obviously this is just the simplest example i was able to think of. what i was trying to illustrate is: i expect [clear, obj 0 0 foo( to clear the entire canvas and then to create an instance of [foo]. using your "delay" message for the "clear", would first create the [foo] object and then delete the entire canvas (including [foo]). of course i could delay the creation of [foo] too, but this would make things over-complicated (imho) and klugdy. i could also do the patching by hand or not use pd alltogether.
if you just delete a some objects using e.g. "find foo, cut", and then create some new ones and try to connect them. Wouldn't the numbering of objects necessary for [connect ...( be invalid now, too? At least the bookkeeping would get even more difficult than it already is.
this is just another example that illustrates (imo), that the automatic delay would not necessarily make things better.
mfg.asdr. IOhannes
Hallo, IOhannes m zmoelnig hat gesagt: // IOhannes m zmoelnig wrote:
Frank Barknecht wrote:
however, i don't think it is a valid assumption for pd itself. in this case, i would highly prefer an error-message to the console (an "exception") and no destruction at all. (since usually you have more complex settings when doing dynamic patching, e.g. [clear, obj 0 0 inlet, obj 0 100 outlet, connect 0 0 1 0( )
"clear" alone may be fine in this case, but I suppose things get hairy
obviously this is just the simplest example i was able to think of. what i was trying to illustrate is: i expect [clear, obj 0 0 foo( to clear the entire canvas and then to create an instance of [foo]. using your "delay" message for the "clear", would first create the [foo] object and then delete the entire canvas (including [foo]).
Risking to appear as an advocate for it: As I understand Tim's approach now, it could work a bit differently. The "clear" would set the "deletable" flag in every object inside the canvas, but it would not do the deletion immediatly. Then the "obj" messages could create objects, which would not have the "deletable" flag set. After the full message is executed, the flagged objects would be deleted, but the unflagged objects could remain. Which in the end would be the same as [clear, obj 0 0 foo(---[delay]---[s pd-sub]
Ciao
Frank Barknecht wrote:
Hallo, IOhannes m zmoelnig hat gesagt: // IOhannes m zmoelnig wrote:
obviously this is just the simplest example i was able to think of. what i was trying to illustrate is: i expect [clear, obj 0 0 foo( to clear the entire canvas and then to create an instance of [foo]. using your "delay" message for the "clear", would first create the [foo] object and then delete the entire canvas (including [foo]).
Risking to appear as an advocate for it: As I understand Tim's
no problem with that. seems like i am risking to be an advocate against it, which is not true: a warning message is better than a crash; but an intelligent handling of the problem is far better than a warning message; however, i believe that a semi-intelligent solution is worse than a warning; if this discussion helps us to make tim's proposal a fully-intelligent (sidenote: i shouldn't have started to use the word "intelligent"; now i can't find my way out...) solution, implementation schould start asap.
approach now, it could work a bit differently. The "clear" would set the "deletable" flag in every object inside the canvas, but it would not do the deletion immediatly. Then the "obj" messages could create objects, which would not have the "deletable" flag set. After the full message is executed, the flagged objects would be deleted, but the unflagged objects could remain. Which in the end would be the same as [clear, obj 0 0 foo(---[delay]---[s pd-sub]
yes this makes sense for simple assumptions. however, what about "consistent data"?
problem1: what happens if you delete a [table foo] object? what happens if you create another [table foo] instance just after deletion? this might be handled explicitely for pd's internal tables, but how about similar (external!) "tables"? problem2: how to deal with singletons? (but thinking about this reveals, that the deletion of singletons' isn't handled "correctly" anyway (actually it is not handled at all - until we have someting like the [closebang]; and once we have this, the problem will be solved anyhow); so this might not be such a big problem)
mfg.adr IOhannes
Hallo, IOhannes m zmoelnig hat gesagt: // IOhannes m zmoelnig wrote:
yes this makes sense for simple assumptions.
Yep, the goal of this discussion should be to really try to find as many pitfalls as possible and to see if they are really pitfalls.
however, what about "consistent data"?
problem1: what happens if you delete a [table foo] object? what happens if you create another [table foo] instance just after deletion? this might be handled explicitely for pd's internal tables, but how about similar (external!) "tables"? problem2: how to deal with singletons? (but thinking about this reveals, that the deletion of singletons' isn't handled "correctly" anyway (actually it is not handled at all - until we have someting like the [closebang]; and once we have this, the problem will be solved anyhow); so this might not be such a big problem)
Funny: I was also thinking about how this may affect to singletons recently.
Anyway one thing we should probably keep in mind: The problems we talk about only occur for objects, that are trying to delete themselves, that want to commit suicide. So we don't need to think too much about "passive" objects that cannot do anything anyway, about objects that don't have outlets and aren't senders. [table] currently seems to be such an object, that can only be killed from the outside.
However it is not clear, that [table] will be such an object for all times. For example data structures already are "active" objects, that can produce messages when manipulated with the mouse or so. Attached is an example for this. Data structures may introduce new complications, as it's also possible to delete the [struct] definition through an action initiated by an instance of this structure. This currently crashes, too (also attached) but deleting a [struct] while instances are still alive can crash Pd anyways, so I'm not sure, if this is a suicide-related problem.
Ciao
hi
Frank Barknecht wrote:
Funny: I was also thinking about how this may affect to singletons recently.
that's the inevitable "great minds..." ;-)
Anyway one thing we should probably keep in mind: The problems we talk about only occur for objects, that are trying to delete themselves, that want to commit suicide. So we don't need to think too much about "passive" objects that cannot do anything anyway, about objects that don't have outlets and aren't senders. [table] currently seems to be such an object, that can only be killed from the outside.
right, i was thinking too simple: flagging "meta"-objects (e.g. abstractions) as deletable; we are really talking about flagging atomic objects, which reduces the problematic cases.
but of course we never know, what exactly a singleton will be.
However it is not clear, that [table] will be such an object for all times. For example data structures already are "active" objects, that
btw, does anybody know why [table] ceased to have inlets? i still think that they were very handy....
mfg.asdr IOhannes