From 1eea48d0c8ecfc3bd98b4246f3dccaaa5ec0b74a Mon Sep 17 00:00:00 2001 From: gblues Date: Mon, 26 Mar 2018 23:35:54 -0700 Subject: [PATCH] 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. --- input/common/hid/device_wiiu_gca.c | 10 ++++++++++ input/common/hid/hid_device_driver.c | 12 +++++++++++- wiiu/input/wiiu_hid.c | 7 ++++--- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/input/common/hid/device_wiiu_gca.c b/input/common/hid/device_wiiu_gca.c index 79fb2ae59d..2cfb601771 100644 --- a/input/common/hid/device_wiiu_gca.c +++ b/input/common/hid/device_wiiu_gca.c @@ -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); } diff --git a/input/common/hid/hid_device_driver.c b/input/common/hid/hid_device_driver.c index e850188f07..13bbf89d40 100644 --- a/input/common/hid/hid_device_driver.c +++ b/input/common/hid/hid_device_driver.c @@ -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)); } diff --git a/wiiu/input/wiiu_hid.c b/wiiu/input/wiiu_hid.c index b9cc8c3af4..7bbca4987e 100644 --- a/wiiu/input/wiiu_hid.c +++ b/wiiu/input/wiiu_hid.c @@ -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); }