Hi all,
In our recent troubleshooting trying to hunt down a mysterious crash at patch closing we uncovered a bug that appears to be present in pd-extended 0.41.4 and 0.42.5, as well as pd vanilla (svn checked out yesterday). Following is reproducible on Linux 9.04 Ubuntu i386.
To reproduce the crash if you run the patch included below (pretty much vanilla version of netsend/netreceive) as follows:
#N canvas 511 186 450 322 10; #X floatatom 80 -44 0 0 0 0 - - -; #X floatatom 71 32 0 0 0 0 - - -; #X obj 125 -117 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1 0 1; #X obj 74 -177 loadbang; #X obj 71 5 netsend 1; #X floatatom 212 -18 5 0 0 0 - - -; #X obj 214 -44 netreceive 3000 1; #X msg 80 -17 send $1; #X msg 71 -157 connect 192.168.1.8 3000; #X obj 122 -95 metro 2; #X obj 151 -53 +; #X msg 114 -69 1; #X connect 0 0 7 0; #X connect 0 0 10 1; #X connect 2 0 9 0; #X connect 3 0 8 0; #X connect 4 0 1 0; #X connect 6 0 5 0; #X connect 7 0 4 0; #X connect 8 0 4 0; #X connect 9 0 11 0; #X connect 10 0 0 0; #X connect 11 0 10 0;
1) save the patch and click on "connect" message 2) start the metro 3) close the patch *without* stopping the metro 4) reopen it again, and you'll find pd reporting that the old connection still exists (explained below) 5) at this point you can start the metro again (it should work) 6) however, when closing the patch pd will crash
Part of the problem:
x->x_fd in netsend_disconnect is the same flag used in netsend_send function, so when one tries to close socket but there is still a stream of data coming in, because x->x_fd is reverted to -1 after the attempt to close the socket, the data keeps coming in through netsend_send function potentially (and I speculate here) preventing socket from closing. This leaves a stale open socket and eventually causes the whole thing to crash.
Below is the problematic code.
static void netsend_disconnect(t_netsend *x) { if (x->x_fd >= 0) { sys_closesocket(x->x_fd); x->x_fd = -1; outlet_float(x->x_obj.ob_outlet, 0); } }
Solution is changing the netsend_disconnect to create a temp value from the x->x_fd, change x->x_fd to -1 to prevent other incoming data from being processed, and only then try to close the socket.
This has apparently fixed part of the problem on our end here.
Please see x_net.c patch below:
--- x_net.c.old 2009-11-18 17:45:24.000000000 -0500 +++ x_net.c 2009-11-18 17:41:38.000000000 -0500 @@ -106,8 +106,9 @@ { if (x->x_fd >= 0) { - sys_closesocket(x->x_fd); - x->x_fd = -1; + int tmp = x->x_fd; + x->x_fd = -1; + sys_closesocket(tmp); outlet_float(x->x_obj.ob_outlet, 0); } }
The problem is this fixes crashing in a non-rt version of Pd. The rt version however still suffers sporadically from the same problem. It may take several tries to instigate it, but when it finally occurs, in my case the reopening of the patch at first misbehaves in that whatever I do on canvas with a mouse or keyboard, everything is being reported twice (e.g. clicking on the toggle creates an on and an off event, creating a new object creates two, typing into it creates 2 letters per each keypress, etc.). After that closing the patch crashes pd. I've had this occur before as well but now at least the other bug with open socket is not there any more.
Any ideas as to why?
Ico