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.QtWidgets import QApplication, QDialog, QMessageBox
|
||||||
from PyQt5.QtCore import (pyqtSlot, QTimer, QEventLoop, Qt, QStandardPaths,
|
from PyQt5.QtCore import (pyqtSlot, QTimer, QEventLoop, Qt, QStandardPaths,
|
||||||
qInstallMessageHandler)
|
qInstallMessageHandler, QObject)
|
||||||
|
|
||||||
import qutebrowser
|
import qutebrowser
|
||||||
import qutebrowser.commands.utils as cmdutils
|
import qutebrowser.commands.utils as cmdutils
|
||||||
@ -390,6 +390,29 @@ class Application(QApplication):
|
|||||||
# downloads
|
# downloads
|
||||||
tabs.start_download.connect(self.downloadmanager.fetch)
|
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):
|
def _recover_pages(self):
|
||||||
"""Try to recover all open pages.
|
"""Try to recover all open pages.
|
||||||
|
|
||||||
@ -467,6 +490,16 @@ class Application(QApplication):
|
|||||||
except Exception:
|
except Exception:
|
||||||
history = []
|
history = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
widgets = self.get_all_widgets()
|
||||||
|
except Exception:
|
||||||
|
widgets = ""
|
||||||
|
|
||||||
|
try:
|
||||||
|
objects = self.get_all_objects()
|
||||||
|
except Exception:
|
||||||
|
objects = ""
|
||||||
|
|
||||||
# Try to shutdown gracefully
|
# Try to shutdown gracefully
|
||||||
try:
|
try:
|
||||||
self.shutdown(do_quit=False)
|
self.shutdown(do_quit=False)
|
||||||
@ -477,7 +510,8 @@ class Application(QApplication):
|
|||||||
except TypeError:
|
except TypeError:
|
||||||
log.destroy.warning("Preventing shutdown failed.")
|
log.destroy.warning("Preventing shutdown failed.")
|
||||||
QApplication.closeAllWindows()
|
QApplication.closeAllWindows()
|
||||||
self._crashdlg = ExceptionCrashDialog(pages, history, exc)
|
self._crashdlg = ExceptionCrashDialog(pages, history, exc, widgets,
|
||||||
|
objects)
|
||||||
ret = self._crashdlg.exec_()
|
ret = self._crashdlg.exec_()
|
||||||
if ret == QDialog.Accepted: # restore
|
if ret == QDialog.Accepted: # restore
|
||||||
self.restart(shutdown=False, pages=pages)
|
self.restart(shutdown=False, pages=pages)
|
||||||
|
@ -21,8 +21,7 @@ import sys
|
|||||||
import types
|
import types
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
|
||||||
from PyQt5.QtCore import (pyqtRemoveInputHook, QEvent, QCoreApplication,
|
from PyQt5.QtCore import pyqtRemoveInputHook, QEvent, QCoreApplication
|
||||||
QObject)
|
|
||||||
|
|
||||||
from qutebrowser.utils.log import misc as logger
|
from qutebrowser.utils.log import misc as logger
|
||||||
|
|
||||||
@ -76,21 +75,14 @@ def debug_crash(typ='exception'):
|
|||||||
@cmdutils.register(debug=True)
|
@cmdutils.register(debug=True)
|
||||||
def debug_all_widgets():
|
def debug_all_widgets():
|
||||||
"""Print a list of all widgets to debug log."""
|
"""Print a list of all widgets to debug log."""
|
||||||
widgets = QCoreApplication.instance().allWidgets()
|
s = QCoreApplication.instance().get_all_widgets()
|
||||||
logger.debug("{} widgets".format(len(widgets)))
|
logger.debug(s)
|
||||||
widgets.sort(key=lambda e: repr(e))
|
|
||||||
for w in widgets:
|
|
||||||
logger.debug(repr(w))
|
|
||||||
|
|
||||||
|
|
||||||
@cmdutils.register(debug=True)
|
@cmdutils.register(debug=True)
|
||||||
def debug_all_objects(obj=None, depth=0):
|
def debug_all_objects(obj=None, depth=0):
|
||||||
"""Dump all children of an object recursively."""
|
"""Dump all children of an object recursively."""
|
||||||
if obj is None:
|
s = QCoreApplication.instance().get_all_objects()
|
||||||
obj = QCoreApplication.instance()
|
logger.debug(s)
|
||||||
for kid in obj.findChildren(QObject):
|
|
||||||
logger.debug(' ' * depth + repr(kid))
|
|
||||||
debug_all_objects(kid, depth + 1)
|
|
||||||
|
|
||||||
|
|
||||||
def log_events(klass):
|
def log_events(klass):
|
||||||
|
@ -148,15 +148,19 @@ class ExceptionCrashDialog(_CrashDialog):
|
|||||||
_pages: A list of the open pages (URLs as strings)
|
_pages: A list of the open pages (URLs as strings)
|
||||||
_cmdhist: A list with the command history (as strings)
|
_cmdhist: A list with the command history (as strings)
|
||||||
_exc: An exception tuple (type, value, traceback)
|
_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._pages = pages
|
||||||
self._cmdhist = cmdhist
|
self._cmdhist = cmdhist
|
||||||
self._exc = exc
|
self._exc = exc
|
||||||
self._btn_quit = None
|
self._btn_quit = None
|
||||||
self._btn_restore = None
|
self._btn_restore = None
|
||||||
self._btn_pastebin = None
|
self._btn_pastebin = None
|
||||||
|
self._widgets = widgets
|
||||||
|
self._objects = objects
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.setModal(True)
|
self.setModal(True)
|
||||||
|
|
||||||
@ -195,6 +199,8 @@ class ExceptionCrashDialog(_CrashDialog):
|
|||||||
("Commandline args", ' '.join(sys.argv[1:])),
|
("Commandline args", ' '.join(sys.argv[1:])),
|
||||||
("Open Pages", '\n'.join(self._pages)),
|
("Open Pages", '\n'.join(self._pages)),
|
||||||
("Command history", '\n'.join(self._cmdhist)),
|
("Command history", '\n'.join(self._cmdhist)),
|
||||||
|
("Widgets", self._widgets),
|
||||||
|
("Objects", self._objects),
|
||||||
]
|
]
|
||||||
try:
|
try:
|
||||||
self._crash_info.append(("Debug log",
|
self._crash_info.append(("Debug log",
|
||||||
|
Loading…
Reference in New Issue
Block a user