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.
This commit is contained in:
Vas Crabb 2017-05-21 17:00:04 +10:00
parent 02e787e3d3
commit b5cbf34a93
4 changed files with 10 additions and 18 deletions

View File

@ -55,7 +55,7 @@ void ti99_colorbus_device::device_config_complete()
void device_ti99_colorbus_interface::interface_config_complete()
{
m_colorbus = downcast<ti99_colorbus_device*>(device().owner());
m_colorbus = dynamic_cast<ti99_colorbus_device*>(device().owner());
}
SLOT_INTERFACE_START( ti99_colorbus_port )

View File

@ -95,7 +95,7 @@ void ti99_joyport_device::device_config_complete()
void device_ti99_joyport_interface::interface_config_complete()
{
m_joyport = downcast<ti99_joyport_device*>(device().owner());
m_joyport = dynamic_cast<ti99_joyport_device*>(device().owner());
}
SLOT_INTERFACE_START( ti99_joystick_port )

View File

@ -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<peribox_device*>(owner());
if (carddev != nullptr)
{
peb->set_slot_loaded(m_slotnumber, this);
m_card = static_cast<ti_expansion_card_device*>(carddev);
}
else
{
peb->set_slot_loaded(m_slotnumber, nullptr);
m_card = nullptr;
}
m_card = downcast<ti_expansion_card_device *>(subdevices().first());
peribox_device *peb = dynamic_cast<peribox_device*>(owner());
if (peb)
peb->set_slot_loaded(m_slotnumber, m_card ? this : nullptr);
}
/*

View File

@ -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");
}
}