Fix crash on exit bug

== DETAILS

Turns out freeing memory that's already been freed is.. bad.

Fix two double-free instances; one due to over-freeing and the other
due to wrong order-of-operations causing a double free.

Also updated logging a little.

== TESTING

The GC adapter still clobbers slot 0, but the "emergency exit" sequence
works to quit RA cleanly.
This commit is contained in:
gblues 2018-03-26 23:35:54 -07:00
parent 6b43defc98
commit 1eea48d0c8
3 changed files with 25 additions and 4 deletions

View File

@ -169,12 +169,19 @@ static joypad_connection_t *register_pad(wiiu_gca_instance_t *instance, int port
joypad_connection_t *result;
if(!instance || !instance->online)
{
RARCH_ERR("[gca]: bad instance\n");
return NULL;
}
slot = pad_connection_find_vacant_pad(hid_instance.pad_list);
if(slot < 0)
{
RARCH_ERR("[gca]: failed to find a free slot\n");
return NULL;
}
RARCH_LOG("[gca]: registering pad in port %d to slot %d\n", port+1, slot);
result = &(hid_instance.pad_list[slot]);
result->iface = &wiiu_gca_pad_connection;
result->data = result->iface->init(instance, slot, hid_instance.os_driver);
@ -237,7 +244,10 @@ static void wiiu_gca_pad_deinit(void *data)
if(pad)
{
if(pad->name)
{
free(pad->name);
pad->name = NULL;
}
free(pad);
}

View File

@ -58,13 +58,16 @@ bool hid_init(hid_driver_instance_t *instance,
input_device_driver_t *pad_driver,
unsigned slots)
{
RARCH_LOG("[hid]: initializing instance with %d pad slots\n", slots);
if(!instance || !hid_driver || !pad_driver || slots > MAX_USERS)
return false;
RARCH_LOG("[hid]: initializing HID subsystem driver...\n");
instance->os_driver_data = hid_driver->init(instance);
if(!instance->os_driver_data)
return false;
RARCH_LOG("[hid]: initializing pad list...\n");
instance->pad_list = pad_connection_init(slots);
if(!instance->pad_list)
{
@ -77,6 +80,8 @@ bool hid_init(hid_driver_instance_t *instance,
instance->os_driver = hid_driver;
instance->pad_driver = pad_driver;
RARCH_LOG("[hid]: instance initialization complete.\n");
return true;
}
@ -90,13 +95,18 @@ void hid_deinit(hid_driver_instance_t *instance)
if(!instance)
return;
pad_connection_destroy(instance->pad_list);
RARCH_LOG("[hid]: destroying instance\n");
if(instance->os_driver && instance->os_driver_data)
{
RARCH_LOG("[hid]: tearing down HID subsystem driver...\n");
instance->os_driver->free(instance->os_driver_data);
}
RARCH_LOG("[hid]: destroying pad data...\n");
pad_connection_destroy(instance->pad_list);
RARCH_LOG("[hid]: wiping instance data...\n");
memset(instance, 0, sizeof(hid_driver_instance_t));
}

View File

@ -430,8 +430,7 @@ static void wiiu_hid_detach(wiiu_hid_t *hid, wiiu_attach_event *event)
wiiu_adapter_t *adapter = synchronized_remove_from_adapters_list(event->handle);
if(adapter) {
adapter->driver->free(adapter->driver_handle);
adapter->driver_handle = NULL;
RARCH_LOG("[hid]: freeing detached pad\n");
delete_adapter(adapter);
}
}
@ -580,8 +579,10 @@ static void wiiu_hid_polling_thread_cleanup(OSThread *thread, void *stack)
* while we are holding the lock. */
if(incomplete == 0)
{
RARCH_LOG("All in-flight reads complete.\n");
while(adapters.list != NULL)
{
RARCH_LOG("[hid]: shutting down adapter..\n");
adapter = adapters.list;
adapters.list = adapter->next;
delete_adapter(adapter);
@ -599,7 +600,6 @@ static void wiiu_hid_polling_thread_cleanup(OSThread *thread, void *stack)
}
}while(incomplete);
RARCH_LOG("All in-flight reads complete.\n");
}
static void wiiu_handle_attach_events(wiiu_hid_t *hid, wiiu_attach_event *list)
@ -725,6 +725,7 @@ static void delete_adapter(wiiu_adapter_t *adapter)
adapter->driver_handle = NULL;
adapter->driver = NULL;
}
free(adapter);
}