Mercurial > pidgin.yaz
comparison libpurple/proxy.c @ 15976:a6a79b8616bf
I commonly see a crash in which socket_ready_cb(), shortly after a laptop wakes from sleep, is passed invalid (previously freed) connect_data. It looks like this:
Thread 0 Crashed:
0 libobjc.A.dylib 0x90a59380 objc_msgSend 16
1 Libgaim 0x0fe23bcd gaim_proxy_connect_data_disconnect 172
2 Libgaim 0x0fe23d63 socket_ready_cb 199
3 com.apple.CoreFoundation 0x90843ffd __CFSocketDoCallback 551
(objc_msgSend is how ObjC routes messages... it's being called because connect_data->cconnect_cb is invalid).
It appears that when this crash happens, the socket is marked as ready just before the computer sleeps; on the next run loop, the callback will be called [socket_ready_cb()]. The computer sleeps and every account is disconnected first, which calls gaim_proxy_connect_cancel_with_handle(), destroying the connect_data. When it awakens, it calls socket_ready_cb() and the crash occurs.
I've added PURPLE_PROXY_CONNECT_DATA_IS_VALID, which takes advantage of the fact that all valid connect_data objects are stored in the handles GSList, just as PURPLE_GAIM_CONNECTION_IS_VALID works.
author | Evan Schoenberg <evan.s@dreskin.net> |
---|---|
date | Sun, 01 Apr 2007 02:17:06 +0000 |
parents | 32c366eeeb99 |
children | 4999bbc52881 |
comparison
equal
deleted
inserted
replaced
15975:328ae2c041c3 | 15976:a6a79b8616bf |
---|---|
85 | 85 |
86 static GSList *handles = NULL; | 86 static GSList *handles = NULL; |
87 | 87 |
88 static void try_connect(PurpleProxyConnectData *connect_data); | 88 static void try_connect(PurpleProxyConnectData *connect_data); |
89 | 89 |
90 /* | |
91 * TODO: Eventually (GObjectification) this bad boy will be removed, because it is | |
92 * a gross fix for a crashy problem. | |
93 */ | |
94 #define PURPLE_PROXY_CONNECT_DATA_IS_VALID(connect_data) g_slist_find(handles, connect_data) | |
95 | |
90 /************************************************************************** | 96 /************************************************************************** |
91 * Proxy structure API | 97 * Proxy structure API |
92 **************************************************************************/ | 98 **************************************************************************/ |
93 PurpleProxyInfo * | 99 PurpleProxyInfo * |
94 purple_proxy_info_new(void) | 100 purple_proxy_info_new(void) |
387 { | 393 { |
388 PurpleProxyConnectData *connect_data = data; | 394 PurpleProxyConnectData *connect_data = data; |
389 int error = 0; | 395 int error = 0; |
390 int ret; | 396 int ret; |
391 | 397 |
398 /* If the socket-connected message had already been triggered when connect_data | |
399 * was destroyed via purple_proxy_connect_cancel(), we may get here with a freed connect_data. | |
400 */ | |
401 if (!PURPLE_PROXY_CONNECT_DATA_IS_VALID(connect_data)) | |
402 return; | |
403 | |
392 purple_debug_info("proxy", "Connected to %s:%d.\n", | 404 purple_debug_info("proxy", "Connected to %s:%d.\n", |
393 connect_data->host, connect_data->port); | 405 connect_data->host, connect_data->port); |
394 | 406 |
395 /* | 407 /* |
396 * purple_input_get_error after a non-blocking connect returns -1 if something is | 408 * purple_input_get_error after a non-blocking connect returns -1 if something is |