Add wiget/object list to crash dialog
This commit is contained in:
parent
87ddfc418e
commit
2b5a1cc322
@ -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)
|
||||
|
@ -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):
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user