GNOME Bugzilla – Bug 326247
gedit crashes trying to execute it multiple times
Last modified: 2006-01-20 14:11:26 UTC
Steps to reproduce: Trying to run gedit multiple times in few seconds (clicking on its icon or executing "gedit & sleep 1; gedit & sleep 0.1; gedit &") makes it crash. Stack trace:
+ Trace 65055
Other information: The program crashes because in server_cb() conn->chan can be NULL because the channel has already been closed, so gedit calls g_io_channel_shutdown() on a NULL channel.
Bastien, this seems a bacon-message-connection bug, can you take a look? Is it ok to just return FALSE without closing when conn->chan is NULL or conn->chan should never be null there and we need to figure out why it is NULL now?
Just return FALSE if the source is NULL (like it is in this case). Please commit to libbacon HEAD before updating your copy.
source is not NULL (gdb is wrong). The problem is is due to the same connection object used for more channels. cd = accept (conn->serverfd, NULL, (guint *)&alen); conn->fd = cd; conn->is_comm = TRUE; setup_connection (conn); // this overwrites conn->channel The problems affects other programs, such as sound-juicer.
To makes things clearer, we are talking about a race here. For instance gedit & sleep 1; gedit > /dev/null & sleep 0.1; gedit > /dev/null & triggers it for me and marco triggered the same problem in sound-juicer too. Paolo Maggi even managed to make gedit open a file name "ChangeLoggedit" by running gedit Changelog & gedit foo :) Unfortunately I tried to make ./testmsg trigger the same problem but I din't manage to find the right timings, maybe because testmsg is just too fast. However the problem seems quite clear: the server has just one "conn" and when two clients connect at the same time 1) messages can mix 2) the first client that exits destroys the channel thus triggering the assertion in the second client
Created attachment 57722 [details] [review] Create a new BaconMessageConnection after accept() This patch creates a new BaconMessageConnection after a new connection is accepted by the server. This connections are kept in a GSList in the server connection so they are freed when the server is freed. I have removed serverfd and server_conn_id as they are no more needed. P.S. gedit does not close its server connection after gtk_main(). Is this wanted?
The server connection should be dropped and the socket unused when gedit exits, so not cleaning up shouldn't really be a problem. I have managed to reproduce the problem (which is solely on the server side) by starting up a server (testmsg), and running 2 concurrent testmsg in a tight loop. Terminal 1: ./testmsg Terminal 2 and 3: while [ $? -eq 0 ] ; do ./testmsg "foooooooooooooooooooooooooooooooooooooooooooooooooooooo" ; done I've not managed to get text mixed up though like Paolo said he did.
I've modified the patch slightly (a few memleaks and not useful initial assignments), and committed it to libbacon CVS, after stress-testing it. Thanks Marco for the patch. 2006-01-20 Bastien Nocera <hadess@hadess.net> * src/bacon-message-connection.c: (setup_connection), (accept_new_connection), (server_cb), (try_server), (try_client), (bacon_message_connection_free): Patch from Marco Barisione <marco.bari@vene.ws> to not share connections from different clients on the server side * src/testmsg.c: (exit_server), (print_stuff), (main): exit after 5 seconds of inactivity from the last message in server mode, free the connection when we're exiting (Closes: #326247) Paolo, please update your copy of this file.
Updated the copy in gedit. Closing the bug.