summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author couriersud <couriersud@gmx.org>2019-02-09 23:06:01 +0100
committer couriersud <couriersud@gmx.org>2019-02-09 23:07:27 +0100
commit83bd138bec869d9d3b78620d7de756763ca2b0cd (patch)
treef03db853d9c15c43327011be7ca78b94e4be128f
parent9d8cb783e3477927db622e0eef63c6e2c3e3ace7 (diff)
netlist: Fix crashes on certain hardware/library combos. (nw)
At least on macosx memory used by an object seems to be invalidated before the dtor is executed. This of course is deadly for child objects with references to the parent-in-deletion which may call back into the parent. One of the worst issues I had to fix. Ever. Lesson learnt: No tricks in dtors. Never.
-rw-r--r--src/lib/netlist/nl_base.cpp19
-rw-r--r--src/lib/netlist/nl_base.h14
-rw-r--r--src/lib/netlist/nl_setup.cpp1
-rw-r--r--src/lib/netlist/plib/pstate.cpp12
-rw-r--r--src/lib/netlist/plib/pstate.h8
5 files changed, 30 insertions, 24 deletions
diff --git a/src/lib/netlist/nl_base.cpp b/src/lib/netlist/nl_base.cpp
index d55e75df6fb..246077788d9 100644
--- a/src/lib/netlist/nl_base.cpp
+++ b/src/lib/netlist/nl_base.cpp
@@ -148,6 +148,10 @@ detail::queue_t::queue_t(netlist_state_t &nl)
{
}
+detail::queue_t::~queue_t()
+{
+}
+
void detail::queue_t::register_state(plib::state_manager_t &manager, const pstring &module)
{
//state().log().debug("register_state\n");
@@ -268,15 +272,6 @@ netlist_state_t::netlist_state_t(const pstring &aname,
}
-netlist_state_t::~netlist_state_t()
-{
- nets().clear();
- m_devices.clear();
-}
-
-
-
-
void netlist_t::stop()
{
log().debug("Printing statistics ...\n");
@@ -695,12 +690,6 @@ detail::net_t::net_t(netlist_state_t &nl, const pstring &aname, core_terminal_t
{
}
-detail::net_t::~net_t()
-{
- state().run_state_manager().remove_save_items(this);
-}
-
-
void detail::net_t::rebuild_list()
{
/* rebuild m_list */
diff --git a/src/lib/netlist/nl_base.h b/src/lib/netlist/nl_base.h
index c2bf42999f3..69ace67d9d7 100644
--- a/src/lib/netlist/nl_base.h
+++ b/src/lib/netlist/nl_base.h
@@ -713,7 +713,7 @@ namespace netlist
};
net_t(netlist_state_t &nl, const pstring &aname, core_terminal_t *mr = nullptr);
- virtual ~net_t();
+ virtual ~net_t() = default;
void reset();
@@ -1221,6 +1221,7 @@ namespace netlist
public:
using entry_t = pqentry_t<net_t *, netlist_time>;
explicit queue_t(netlist_state_t &nl);
+ ~queue_t();
protected:
@@ -1249,7 +1250,7 @@ namespace netlist
std::unique_ptr<callbacks_t> &&callbacks,
std::unique_ptr<setup_t> &&setup);
- ~netlist_state_t();
+ ~netlist_state_t() = default;
friend class netlist_t; // allow access to private members
@@ -1320,11 +1321,20 @@ namespace netlist
m_devices.insert(m_devices.end(), { name, std::move(dev) });
}
+ /**
+ * @brief Remove device
+ *
+ * Care needs to be applied if this is called to remove devices with
+ * sub-devices which may have registered state.
+ *
+ * @param dev Device to be removed
+ */
void remove_dev(core_device_t *dev)
{
for (auto it = m_devices.begin(); it != m_devices.end(); it++)
if (it->second.get() == dev)
{
+ m_state.remove_save_items(dev);
m_devices.erase(it);
return;
}
diff --git a/src/lib/netlist/nl_setup.cpp b/src/lib/netlist/nl_setup.cpp
index 2fad9ea4836..cfc9a7eb484 100644
--- a/src/lib/netlist/nl_setup.cpp
+++ b/src/lib/netlist/nl_setup.cpp
@@ -1000,6 +1000,7 @@ void setup_t::delete_empty_nets()
if (x->num_cons() == 0)
{
x->state().log().verbose("Deleting net {1} ...", x->name());
+ x->state().run_state_manager().remove_save_items(x.get());
return true;
}
else
diff --git a/src/lib/netlist/plib/pstate.cpp b/src/lib/netlist/plib/pstate.cpp
index 14d0da3d374..3bd93ed4f8e 100644
--- a/src/lib/netlist/plib/pstate.cpp
+++ b/src/lib/netlist/plib/pstate.cpp
@@ -18,19 +18,19 @@ void state_manager_t::save_state_ptr(const void *owner, const pstring &stname, c
void state_manager_t::remove_save_items(const void *owner)
{
- for (auto i = m_save.begin(); i != m_save.end(); )
+ auto i = m_save.end();
+ while (i != m_save.begin())
{
+ i--;
if (i->get()->m_owner == owner)
i = m_save.erase(i);
- else
- i++;
}
- for (auto i = m_custom.begin(); i != m_custom.end(); )
+ i = m_custom.end();
+ while (i > m_custom.begin())
{
+ i--;
if (i->get()->m_owner == owner)
i = m_custom.erase(i);
- else
- i++;
}
}
diff --git a/src/lib/netlist/plib/pstate.h b/src/lib/netlist/plib/pstate.h
index 2e6026f355a..290333bf87d 100644
--- a/src/lib/netlist/plib/pstate.h
+++ b/src/lib/netlist/plib/pstate.h
@@ -117,7 +117,13 @@ public:
void post_load();
void remove_save_items(const void *owner);
- const entry_t::list_t &save_list() const { return m_save; }
+ const std::vector<const entry_t *> save_list() const
+ {
+ std::vector<const entry_t *> ret;
+ for (auto &i : m_save)
+ ret.push_back(i.get());
+ return ret;
+ }
void save_state_ptr(const void *owner, const pstring &stname, const datatype_t &dt, const std::size_t count, void *ptr);