Add wiget/object list to crash dialog

This commit is contained in:
Florian Bruhin 2014-06-17 23:04:58 +02:00
parent 87ddfc418e
commit 2b5a1cc322
3 changed files with 48 additions and 16 deletions

View File

@ -28,7 +28,7 @@ from base64 import b64encode
from PyQt5.QtWidgets import QApplication, QDialog, QMessageBox
from PyQt5.QtCore import (pyqtSlot, QTimer, QEventLoop, Qt, QStandardPaths,
qInstallMessageHandler)
qInstallMessageHandler, QObject)
import qutebrowser
import qutebrowser.commands.utils as cmdutils
@ -390,6 +390,29 @@ class Application(QApplication):
# downloads
tabs.start_download.connect(self.downloadmanager.fetch)
def get_all_widgets(self):
"""Get a string list of all widgets."""
lines = []
widgets = self.allWidgets()
widgets.sort(key=lambda e: repr(e))
lines.append("{} widgets".format(len(widgets)))
for w in widgets:
lines.append(repr(w))
return '\n'.join(lines)
def get_all_objects(self, obj=None, depth=0, lines=None):
"""Get all children of an object recursively as a string."""
if lines is None:
lines = []
if obj is None:
obj = self
for kid in obj.findChildren(QObject):
lines.append(' ' * depth + repr(kid))
self.get_all_objects(kid, depth + 1, lines)
if depth == 0:
lines.insert(0, '{} objects:'.format(len(lines)))
return '\n'.join(lines)
def _recover_pages(self):
"""Try to recover all open pages.
@ -467,6 +490,16 @@ class Application(QApplication):
except Exception:
history = []
try:
widgets = self.get_all_widgets()
except Exception:
widgets = ""
try:
objects = self.get_all_objects()
except Exception:
objects = ""
# Try to shutdown gracefully
try:
self.shutdown(do_quit=False)
@ -477,7 +510,8 @@ class Application(QApplication):
except TypeError:
log.destroy.warning("Preventing shutdown failed.")
QApplication.closeAllWindows()
self._crashdlg = ExceptionCrashDialog(pages, history, exc)
self._crashdlg = ExceptionCrashDialog(pages, history, exc, widgets,
objects)
ret = self._crashdlg.exec_()
if ret == QDialog.Accepted: # restore
self.restart(shutdown=False, pages=pages)

View File

@ -21,8 +21,7 @@ import sys
import types
from functools import wraps
from PyQt5.QtCore import (pyqtRemoveInputHook, QEvent, QCoreApplication,
QObject)
from PyQt5.QtCore import pyqtRemoveInputHook, QEvent, QCoreApplication
from qutebrowser.utils.log import misc as logger
@ -76,21 +75,14 @@ def debug_crash(typ='exception'):
@cmdutils.register(debug=True)
def debug_all_widgets():
"""Print a list of all widgets to debug log."""
widgets = QCoreApplication.instance().allWidgets()
logger.debug("{} widgets".format(len(widgets)))
widgets.sort(key=lambda e: repr(e))
for w in widgets:
logger.debug(repr(w))
s = QCoreApplication.instance().get_all_widgets()
logger.debug(s)
@cmdutils.register(debug=True)
def debug_all_objects(obj=None, depth=0):
"""Dump all children of an object recursively."""
if obj is None:
obj = QCoreApplication.instance()
for kid in obj.findChildren(QObject):
logger.debug(' ' * depth + repr(kid))
debug_all_objects(kid, depth + 1)
s = QCoreApplication.instance().get_all_objects()
logger.debug(s)
def log_events(klass):

View File

@ -148,15 +148,19 @@ class ExceptionCrashDialog(_CrashDialog):
_pages: A list of the open pages (URLs as strings)
_cmdhist: A list with the command history (as strings)
_exc: An exception tuple (type, value, traceback)
_widgets: A list of active widgets as string.
_objects: A list of all QObjects as string.
"""
def __init__(self, pages, cmdhist, exc, parent=None):
def __init__(self, pages, cmdhist, exc, widgets, objects, parent=None):
self._pages = pages
self._cmdhist = cmdhist
self._exc = exc
self._btn_quit = None
self._btn_restore = None
self._btn_pastebin = None
self._widgets = widgets
self._objects = objects
super().__init__(parent)
self.setModal(True)
@ -195,6 +199,8 @@ class ExceptionCrashDialog(_CrashDialog):
("Commandline args", ' '.join(sys.argv[1:])),
("Open Pages", '\n'.join(self._pages)),
("Command history", '\n'.join(self._cmdhist)),
("Widgets", self._widgets),
("Objects", self._objects),
]
try:
self._crash_info.append(("Debug log",