pidgin/pidgin

Fix memory issues at shutdown

2020-07-27, Elliott S
b119cf7a05b9
Parents 2f45a03838e9
Children 81417b812648
Fix memory issues at shutdown

* Fix double-free of accounts menu widgets.
On shutdown, these are part of the menu, and are already destroyed, so
we can't destroy them again as part of finalize, which happens in the
hash table removal.

* Silence some warnings at shutdown.
If the IO operation is cancelled, then it doesn't need to be printed or
considered an error.

* Add config.h back to jabber.h.
This header checks config values (e.g., `HAVE_CYRUS_SASL`), so it should
include config, or else it falls to C sources to do it. And if they
don't, then they end up with incorrect struct offsets, which is causing
weird memory errors as stuff is put in the wrong place.

Testing Done:
valgrind with an xmpp account enabled.

Reviewed at https://reviews.imfreedom.org/r/51/
--- a/libpurple/protocols/jabber/jabber.c Fri Jul 24 04:43:46 2020 -0500
+++ b/libpurple/protocols/jabber/jabber.c Mon Jul 27 00:20:24 2020 -0500
@@ -380,8 +380,10 @@
if (!result) {
purple_queued_output_stream_clear_queue(stream);
- g_prefix_error(&error, "%s", _("Lost connection with server: "));
- purple_connection_take_error(js->gc, error);
+ if (error->code != G_IO_ERROR_CANCELLED) {
+ g_prefix_error(&error, "%s", _("Lost connection with server: "));
+ purple_connection_take_error(js->gc, error);
+ }
}
}
--- a/libpurple/protocols/jabber/jabber.h Fri Jul 24 04:43:46 2020 -0500
+++ b/libpurple/protocols/jabber/jabber.h Mon Jul 27 00:20:24 2020 -0500
@@ -61,6 +61,8 @@
#include <gio/gio.h>
#include <libsoup/soup.h>
+#include <config.h>
+
#include <purple.h>
#include "namespaces.h"
--- a/libpurple/purple-gio.c Fri Jul 24 04:43:46 2020 -0500
+++ b/libpurple/purple-gio.c Mon Jul 27 00:20:24 2020 -0500
@@ -49,9 +49,10 @@
/* Close input stream, from wrapper or GIOStream */
if (!g_input_stream_close(data->input, NULL, &error)) {
- purple_debug_warning("gio",
- "Error closing input stream: %s",
- error->message);
+ if (error->code != G_IO_ERROR_CANCELLED) {
+ purple_debug_warning("gio", "Error closing input stream: %s",
+ error->message);
+ }
g_clear_error(&error);
}
@@ -59,9 +60,10 @@
/* Close output stream, from wrapper or GIOStream */
if (!g_output_stream_close(data->output, NULL, &error)) {
- purple_debug_warning("gio",
- "Error closing output stream: %s",
- error->message);
+ if (error->code != G_IO_ERROR_CANCELLED) {
+ purple_debug_warning("gio", "Error closing output stream: %s",
+ error->message);
+ }
g_clear_error(&error);
}
@@ -69,9 +71,10 @@
/* Close io stream */
if (!g_io_stream_close(data->stream, NULL, &error)) {
- purple_debug_warning("gio",
- "Error closing stream: %s",
- error->message);
+ if (error->code != G_IO_ERROR_CANCELLED) {
+ purple_debug_warning("gio", "Error closing stream: %s",
+ error->message);
+ }
g_clear_error(&error);
}
--- a/pidgin/pidginaccountsmenu.c Fri Jul 24 04:43:46 2020 -0500
+++ b/pidgin/pidginaccountsmenu.c Mon Jul 27 00:20:24 2020 -0500
@@ -80,7 +80,10 @@
GtkWidget *item = NULL, *submenu = NULL;
/* if the account is in the disabled list, delete its widget */
- g_hash_table_remove(menu->disabled_items, account);
+ if (g_hash_table_lookup_extended(menu->disabled_items, account, NULL, &item)) {
+ g_clear_pointer(&item, gtk_widget_destroy);
+ g_hash_table_remove(menu->disabled_items, account);
+ }
item = pidgin_accounts_menu_create_account_menu_item(menu, account);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
@@ -102,7 +105,10 @@
GtkWidget *item = NULL;
/* if the account is in the enabled list, delete its widget */
- g_hash_table_remove(menu->account_items, account);
+ if (g_hash_table_lookup_extended(menu->account_items, account, NULL, &item)) {
+ g_clear_pointer(&item, gtk_widget_destroy);
+ g_hash_table_remove(menu->account_items, account);
+ }
item = pidgin_accounts_menu_create_account_menu_item(menu, account);
g_signal_connect(G_OBJECT(item), "activate",
@@ -173,11 +179,9 @@
/* create our storage for the items */
menu->account_items = g_hash_table_new_full(g_direct_hash, g_direct_equal,
- g_object_unref,
- (GDestroyNotify)gtk_widget_destroy);
+ g_object_unref, NULL);
menu->disabled_items = g_hash_table_new_full(g_direct_hash, g_direct_equal,
- g_object_unref,
- (GDestroyNotify)gtk_widget_destroy);
+ g_object_unref, NULL);
/* add all of the existing accounts */
pidgin_accounts_menu_add_current(menu);