Export state objects as pickle files

This should better ensure debugging an issue will have all the relevant
info at the ready.
This commit is contained in:
2Shirt 2021-03-25 21:15:56 -06:00
parent 3f48b10942
commit 9818d5196f
Signed by: 2Shirt
GPG key ID: 152FAC923B0E132C
3 changed files with 41 additions and 14 deletions

View file

@ -958,6 +958,7 @@ class State():
debug_dir.mkdir() debug_dir.mkdir()
# State (self) # State (self)
std.save_pickles({'state': self}, debug_dir)
with open(f'{debug_dir}/state.report', 'a') as _f: with open(f'{debug_dir}/state.report', 'a') as _f:
_f.write('[Debug report]\n') _f.write('[Debug report]\n')
_f.write('\n'.join(debug.generate_object_report(self))) _f.write('\n'.join(debug.generate_object_report(self)))

View file

@ -331,6 +331,7 @@ class State():
debug_dir.mkdir() debug_dir.mkdir()
# State (self) # State (self)
std.save_pickles({'state': self}, debug_dir)
with open(f'{debug_dir}/state.report', 'a') as _f: with open(f'{debug_dir}/state.report', 'a') as _f:
_f.write('\n'.join(debug.generate_object_report(self))) _f.write('\n'.join(debug.generate_object_report(self)))

View file

@ -2,11 +2,13 @@
# pylint: disable=too-many-lines # pylint: disable=too-many-lines
# vim: sts=2 sw=2 ts=2 # vim: sts=2 sw=2 ts=2
import inspect
import itertools import itertools
import logging import logging
import lzma import lzma
import os import os
import pathlib import pathlib
import pickle
import platform import platform
import re import re
import socket import socket
@ -26,6 +28,7 @@ from wk.cfg.main import (
WIDTH, WIDTH,
) )
from wk.cfg.net import CRASH_SERVER from wk.cfg.net import CRASH_SERVER
from wk.log import get_root_logger_path
# STATIC VARIABLES # STATIC VARIABLES
@ -863,23 +866,26 @@ def major_exception():
LOG.critical('Major exception encountered', exc_info=True) LOG.critical('Major exception encountered', exc_info=True)
print_error('Major exception', log=False) print_error('Major exception', log=False)
print_warning(SUPPORT_MESSAGE) print_warning(SUPPORT_MESSAGE)
if ENABLED_UPLOAD_DATA:
print_warning('Also, please run upload-logs to help debugging!')
print(traceback.format_exc()) print(traceback.format_exc())
# Build report # TODO: Decide to remove or reinstate following section
report = generate_debug_report() ## Build report
#report = generate_debug_report()
# Upload details ## Upload details
prompt = f'Upload details to {CRASH_SERVER.get("Name", "?")}?' #prompt = f'Upload details to {CRASH_SERVER.get("Name", "?")}?'
if ENABLED_UPLOAD_DATA and ask(prompt): #if ENABLED_UPLOAD_DATA and ask(prompt):
print('Uploading... ', end='', flush=True) # print('Uploading... ', end='', flush=True)
try: # try:
upload_debug_report(report, reason='CRASH') # upload_debug_report(report, reason='CRASH')
except Exception: #pylint: disable=broad-except # except Exception: #pylint: disable=broad-except
print_error('FAILED', log=False) # print_error('FAILED', log=False)
LOG.error('Upload failed', exc_info=True) # LOG.error('Upload failed', exc_info=True)
else: # else:
print_success('SUCCESS', log=False) # print_success('SUCCESS', log=False)
LOG.info('Upload successful') # LOG.info('Upload successful')
# Done # Done
pause('Press Enter to exit... ') pause('Press Enter to exit... ')
@ -960,6 +966,25 @@ def print_warning(msg, log=True, **kwargs):
LOG.warning(msg) LOG.warning(msg)
def save_pickles(obj_dict, out_path=None):
"""Save dict of objects using pickle."""
LOG.info('Saving pickles')
# Set path
if not out_path:
out_path = pathlib.Path(f'{get_root_logger_path().parent}/debug')
# Save pickles
try:
for name, obj in obj_dict.copy().items():
if name.startswith('__') or inspect.ismodule(obj):
continue
with open(f'{out_path}/{name}.pickle', 'wb') as _f:
pickle.dump(obj, _f, protocol=pickle.HIGHEST_PROTOCOL)
except Exception: # pylint: disable=broad-except
LOG.error('Failed to save all the pickles', exc_info=True)
def set_title(title): def set_title(title):
"""Set window title.""" """Set window title."""
LOG.debug('title: %s', title) LOG.debug('title: %s', title)