So I wanted to fix that SIGSEGV that’s happening when closing Pidgin3 or when disconnecting an account. The SIGSEGV happens for example when disconnecting an IRCv3 account at parent_class->disconnect
in the following code:
static gboolean
purple_ircv3_connection_disconnect(PurpleConnection *purple_connection,
GError **error)
{
PurpleIRCv3Connection *connection = NULL;
PurpleIRCv3ConnectionPrivate *priv = NULL;
PurpleConnectionClass *parent_class = NULL;
g_return_val_if_fail(PURPLE_IRCV3_IS_CONNECTION(purple_connection), FALSE);
/* Chain up to our parent's disconnect to do initial clean up. */
parent_class = PURPLE_CONNECTION_CLASS(purple_ircv3_connection_parent_class);
parent_class->disconnect(purple_connection, error);
connection = PURPLE_IRCV3_CONNECTION(purple_connection);
priv = purple_ircv3_connection_get_instance_private(connection);
/* TODO: send QUIT command. */
g_clear_object(&priv->client);
return TRUE;
}
This is because the disconnect
function pointer is zero. So the solution seems easy in just checking it for zero before calling it. But I’m wondering why that code is even there in the first place. Because similar code is in Bonjour and XMPP too. Please correct me if I’m wrong but my understanding is that parent_class
is PurpleConnection and in purple_connection_disconnect
there’s this code:
/* Dispatch to the connection's disconnect method. */
klass = PURPLE_CONNECTION_GET_CLASS(connection);
if(klass != NULL && klass->disconnect != NULL) {
ret = klass->disconnect(connection, error);
}
Which is the code that calls purple_ircv3_connection_disconnect
in the first place and I don’t understand why purple_ircv3_connection_disconnect
would need to call its parent’s disconnect again.