mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-02-25 18:55:27 -06:00
baseclass: Track object lifetime to help debug ref leaks
This commit is contained in:
parent
96085b13a8
commit
85340ca491
@ -42,6 +42,9 @@ class vmmGObject(gobject.GObject):
|
|||||||
self._gobject_timeouts = []
|
self._gobject_timeouts = []
|
||||||
self._gconf_handles = []
|
self._gconf_handles = []
|
||||||
|
|
||||||
|
self._object_key = str(self)
|
||||||
|
self.config.add_object(self._object_key)
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
# Do any cleanup required to drop reference counts so object is
|
# Do any cleanup required to drop reference counts so object is
|
||||||
# actually reaped by python. Usually means unregistering callbacks
|
# actually reaped by python. Usually means unregistering callbacks
|
||||||
@ -81,6 +84,14 @@ class vmmGObject(gobject.GObject):
|
|||||||
from virtManager import halhelper
|
from virtManager import halhelper
|
||||||
return halhelper.get_hal_helper()
|
return halhelper.get_hal_helper()
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
if hasattr(gobject.GObject, "__del__"):
|
||||||
|
getattr(gobject.GObject, "__del__")(self)
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.config.remove_object(self._object_key)
|
||||||
|
except:
|
||||||
|
logging.exception("Error removing %s" % self._object_key)
|
||||||
|
|
||||||
class vmmGObjectUI(vmmGObject):
|
class vmmGObjectUI(vmmGObject):
|
||||||
def __init__(self, filename, windowname):
|
def __init__(self, filename, windowname):
|
||||||
|
@ -115,6 +115,8 @@ class vmmConfig(object):
|
|||||||
self.hv_packages = []
|
self.hv_packages = []
|
||||||
self.libvirt_packages = []
|
self.libvirt_packages = []
|
||||||
|
|
||||||
|
self._objects = []
|
||||||
|
|
||||||
self.status_icons = {
|
self.status_icons = {
|
||||||
libvirt.VIR_DOMAIN_BLOCKED: gtk.gdk.pixbuf_new_from_file_at_size(self.get_icon_dir() + "/state_running.png", 18, 18),
|
libvirt.VIR_DOMAIN_BLOCKED: gtk.gdk.pixbuf_new_from_file_at_size(self.get_icon_dir() + "/state_running.png", 18, 18),
|
||||||
libvirt.VIR_DOMAIN_CRASHED: gtk.gdk.pixbuf_new_from_file_at_size(self.get_icon_dir() + "/state_crashed.png", 18, 18),
|
libvirt.VIR_DOMAIN_CRASHED: gtk.gdk.pixbuf_new_from_file_at_size(self.get_icon_dir() + "/state_crashed.png", 18, 18),
|
||||||
@ -179,6 +181,15 @@ class vmmConfig(object):
|
|||||||
def remove_notifier(self, h):
|
def remove_notifier(self, h):
|
||||||
self.conf.notify_remove(h)
|
self.conf.notify_remove(h)
|
||||||
|
|
||||||
|
# Used for debugging reference leaks, we keep track of all objects
|
||||||
|
# come and go so we can do a leak report at app shutdown
|
||||||
|
def add_object(self, obj):
|
||||||
|
self._objects.append(obj)
|
||||||
|
def remove_object(self, obj):
|
||||||
|
self._objects.remove(obj)
|
||||||
|
def get_objects(self):
|
||||||
|
return self._objects[:]
|
||||||
|
|
||||||
# Per-VM/Connection/Connection Host Option dealings
|
# Per-VM/Connection/Connection Host Option dealings
|
||||||
def _perconn_helper(self, uri, pref_func, func_type, value=None):
|
def _perconn_helper(self, uri, pref_func, func_type, value=None):
|
||||||
suffix = "connection_prefs/%s" % gconf.escape_key(uri, len(uri))
|
suffix = "connection_prefs/%s" % gconf.escape_key(uri, len(uri))
|
||||||
|
@ -47,6 +47,9 @@ from virtManager.error import vmmErrorDialog
|
|||||||
from virtManager.systray import vmmSystray
|
from virtManager.systray import vmmSystray
|
||||||
import virtManager.util as util
|
import virtManager.util as util
|
||||||
|
|
||||||
|
# Enable this to get a report of leaked objects on app shutdown
|
||||||
|
debug_ref_leaks = False
|
||||||
|
|
||||||
def default_uri():
|
def default_uri():
|
||||||
tryuri = None
|
tryuri = None
|
||||||
if os.path.exists("/var/lib/xend") and os.path.exists("/proc/xen"):
|
if os.path.exists("/var/lib/xend") and os.path.exists("/proc/xen"):
|
||||||
@ -473,6 +476,12 @@ class vmmEngine(vmmGObject):
|
|||||||
conns = self.connections.values()
|
conns = self.connections.values()
|
||||||
for conn in conns:
|
for conn in conns:
|
||||||
conn["connection"].close()
|
conn["connection"].close()
|
||||||
|
self.connections = {}
|
||||||
|
|
||||||
|
if debug_ref_leaks:
|
||||||
|
for name in self.config.get_objects():
|
||||||
|
logging.debug("Leaked %s" % name)
|
||||||
|
|
||||||
logging.debug("Exiting app normally.")
|
logging.debug("Exiting app normally.")
|
||||||
gtk.main_quit()
|
gtk.main_quit()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user