From b5cbf34a936d9fe5b1fffdeba8bdf4989a1e0340 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Sun, 21 May 2017 17:00:04 +1000 Subject: Fix crashes in -listxml in debug builds * Make -listxml instantiate slot devices in slots rather than under the machine root * Use dynamic_cast rather than static_cast or downcast on parent device in TI-99 slot/card devices (nw) There are still very real issues present. When -listxml, -listroms, -verifyroms, etc. instantiate individual devices, they don't have the information necessary to instantiate the expected parent device. So slots won't be children of the bus they expect to be attached to, and cards won't be in their usual slots. It's unsafe to use static_cast<> on owner at the best of times, and doing anything with the result is likely to cause silent memory corruption during listxml (this was previously happening with the TI-99 peripheral box slot device). You can't use downcast<> at configuration complete time either, as that degenerates to a static_cast<> in release builds anyway, and it will cause a crash in -listxml in debug builds as we had before. The choices are to use a dynamic_cast and check the result before doing anything with it before device start time, or wait for device start time and use downcast<> at that point. --- src/devices/bus/ti99/colorbus/colorbus.cpp | 2 +- src/devices/bus/ti99/joyport/joyport.cpp | 2 +- src/devices/bus/ti99/peb/peribox.cpp | 16 ++++------------ src/frontend/mame/info.cpp | 8 ++++---- 4 files changed, 10 insertions(+), 18 deletions(-) diff --git a/src/devices/bus/ti99/colorbus/colorbus.cpp b/src/devices/bus/ti99/colorbus/colorbus.cpp index f157d564861..b9c938f8fde 100644 --- a/src/devices/bus/ti99/colorbus/colorbus.cpp +++ b/src/devices/bus/ti99/colorbus/colorbus.cpp @@ -55,7 +55,7 @@ void ti99_colorbus_device::device_config_complete() void device_ti99_colorbus_interface::interface_config_complete() { - m_colorbus = downcast(device().owner()); + m_colorbus = dynamic_cast(device().owner()); } SLOT_INTERFACE_START( ti99_colorbus_port ) diff --git a/src/devices/bus/ti99/joyport/joyport.cpp b/src/devices/bus/ti99/joyport/joyport.cpp index d41a005258c..3ad74068913 100644 --- a/src/devices/bus/ti99/joyport/joyport.cpp +++ b/src/devices/bus/ti99/joyport/joyport.cpp @@ -95,7 +95,7 @@ void ti99_joyport_device::device_config_complete() void device_ti99_joyport_interface::interface_config_complete() { - m_joyport = downcast(device().owner()); + m_joyport = dynamic_cast(device().owner()); } SLOT_INTERFACE_START( ti99_joystick_port ) diff --git a/src/devices/bus/ti99/peb/peribox.cpp b/src/devices/bus/ti99/peb/peribox.cpp index add22015f2d..d63c824c3ae 100644 --- a/src/devices/bus/ti99/peb/peribox.cpp +++ b/src/devices/bus/ti99/peb/peribox.cpp @@ -701,18 +701,10 @@ void peribox_slot_device::device_start() void peribox_slot_device::device_config_complete() { m_slotnumber = get_index_from_tagname(); - device_t *carddev = subdevices().first(); - peribox_device *peb = static_cast(owner()); - if (carddev != nullptr) - { - peb->set_slot_loaded(m_slotnumber, this); - m_card = static_cast(carddev); - } - else - { - peb->set_slot_loaded(m_slotnumber, nullptr); - m_card = nullptr; - } + m_card = downcast(subdevices().first()); + peribox_device *peb = dynamic_cast(owner()); + if (peb) + peb->set_slot_loaded(m_slotnumber, m_card ? this : nullptr); } /* diff --git a/src/frontend/mame/info.cpp b/src/frontend/mame/info.cpp index dcbcc3bb3b4..8af0df55e60 100644 --- a/src/frontend/mame/info.cpp +++ b/src/frontend/mame/info.cpp @@ -1607,7 +1607,7 @@ void info_xml_creator::output_images(device_t &device, const char *root_tag) void info_xml_creator::output_slots(machine_config &config, device_t &device, const char *root_tag, device_type_set *devtypes) { - for (const device_slot_interface &slot : slot_interface_iterator(device)) + for (device_slot_interface &slot : slot_interface_iterator(device)) { // shall we list fixed slots as non-configurable? bool const listed(!slot.fixed() && strcmp(slot.device().tag(), device.tag())); @@ -1630,12 +1630,12 @@ void info_xml_creator::output_slots(machine_config &config, device_t &device, co { if (devtypes || (listed && option.second->selectable())) { - device_t *const dev = config.device_add(&device, "_dummy", option.second->devtype(), 0); + device_t *const dev = config.device_add(&slot.device(), "_dummy", option.second->devtype(), 0); if (!dev->configured()) dev->config_complete(); if (devtypes) - for (device_t &device : device_iterator(*dev)) devtypes->insert(&device.type()); + for (device_t &subdevice : device_iterator(*dev)) devtypes->insert(&subdevice.type()); if (listed && option.second->selectable()) { @@ -1647,7 +1647,7 @@ void info_xml_creator::output_slots(machine_config &config, device_t &device, co fprintf(m_output, "/>\n"); } - config.device_remove(&device, "_dummy"); + config.device_remove(&slot.device(), "_dummy"); } } -- cgit v1.2.3