##// END OF EJS Templates
Improve instructions on reporting crash...
Samuel Lelièvre -
Show More
@@ -1,218 +1,225 b''
1 1 # encoding: utf-8
2 2 """sys.excepthook for IPython itself, leaves a detailed report on disk.
3 3
4 4 Authors:
5 5
6 6 * Fernando Perez
7 7 * Brian E. Granger
8 8 """
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
12 12 # Copyright (C) 2008-2011 The IPython Development Team
13 13 #
14 14 # Distributed under the terms of the BSD License. The full license is in
15 15 # the file COPYING, distributed as part of this software.
16 16 #-----------------------------------------------------------------------------
17 17
18 18 #-----------------------------------------------------------------------------
19 19 # Imports
20 20 #-----------------------------------------------------------------------------
21 21
22 22 import os
23 23 import sys
24 24 import traceback
25 25 from pprint import pformat
26 26
27 27 from IPython.core import ultratb
28 28 from IPython.core.release import author_email
29 29 from IPython.utils.sysinfo import sys_info
30 30 from IPython.utils.py3compat import input
31 31
32 32 #-----------------------------------------------------------------------------
33 33 # Code
34 34 #-----------------------------------------------------------------------------
35 35
36 36 # Template for the user message.
37 37 _default_message_template = """\
38 38 Oops, {app_name} crashed. We do our best to make it stable, but...
39 39
40 40 A crash report was automatically generated with the following information:
41 41 - A verbatim copy of the crash traceback.
42 42 - A copy of your input history during this session.
43 43 - Data on your current {app_name} configuration.
44 44
45 45 It was left in the file named:
46 46 \t'{crash_report_fname}'
47 47 If you can email this file to the developers, the information in it will help
48 them in understanding and correcting the problem. Please include information
49 about your operating system: is it Linux, macOS, Windows, other, and which
50 version, for example Ubuntu 16.04, macOS 10.13.2, Windows 10 Pro 64-bit...
51 Please also include information on how you installed {app_name}.
48 them in understanding and correcting the problem.
52 49
53 50 You can mail it to: {contact_name} at {contact_email}
54 51 with the subject '{app_name} Crash Report'.
55 52
56 53 If you want to do it now, the following command will work (under Unix):
57 54 mail -s '{app_name} Crash Report' {contact_email} < {crash_report_fname}
58 55
56 Please also include in your email:
57 - information about your operating system: is it Linux, macOS, Windows, other,
58 and which version, for example Ubuntu 16.04, macOS 10.13.2, Windows 10 Pro,
59 is it 32-bit or 64-bit, ...
60 - information on how you installed {app_name}: from binary, compiled from source,
61 via Docker, on a virtual machine...
62 - information on how to reproduce the crash: what exact sequence of instructions
63 can one input to get the same crash? Ideally, find a minimal yet complete
64 sequence of instructions that yields the crash.
65
59 66 To ensure accurate tracking of this issue, please file a report about it at:
60 67 {bug_tracker}
61 68 """
62 69
63 70 _lite_message_template = """
64 71 If you suspect this is an IPython bug, please report it at:
65 72 https://github.com/ipython/ipython/issues
66 73 or send an email to the mailing list at {email}
67 74
68 75 You can print a more detailed traceback right now with "%tb", or use "%debug"
69 76 to interactively debug it.
70 77
71 78 Extra-detailed tracebacks for bug-reporting purposes can be enabled via:
72 79 {config}Application.verbose_crash=True
73 80 """
74 81
75 82
76 83 class CrashHandler(object):
77 84 """Customizable crash handlers for IPython applications.
78 85
79 86 Instances of this class provide a :meth:`__call__` method which can be
80 87 used as a ``sys.excepthook``. The :meth:`__call__` signature is::
81 88
82 89 def __call__(self, etype, evalue, etb)
83 90 """
84 91
85 92 message_template = _default_message_template
86 93 section_sep = '\n\n'+'*'*75+'\n\n'
87 94
88 95 def __init__(self, app, contact_name=None, contact_email=None,
89 96 bug_tracker=None, show_crash_traceback=True, call_pdb=False):
90 97 """Create a new crash handler
91 98
92 99 Parameters
93 100 ----------
94 101 app : Application
95 102 A running :class:`Application` instance, which will be queried at
96 103 crash time for internal information.
97 104
98 105 contact_name : str
99 106 A string with the name of the person to contact.
100 107
101 108 contact_email : str
102 109 A string with the email address of the contact.
103 110
104 111 bug_tracker : str
105 112 A string with the URL for your project's bug tracker.
106 113
107 114 show_crash_traceback : bool
108 115 If false, don't print the crash traceback on stderr, only generate
109 116 the on-disk report
110 117
111 118 Non-argument instance attributes:
112 119
113 120 These instances contain some non-argument attributes which allow for
114 121 further customization of the crash handler's behavior. Please see the
115 122 source for further details.
116 123 """
117 124 self.crash_report_fname = "Crash_report_%s.txt" % app.name
118 125 self.app = app
119 126 self.call_pdb = call_pdb
120 127 #self.call_pdb = True # dbg
121 128 self.show_crash_traceback = show_crash_traceback
122 129 self.info = dict(app_name = app.name,
123 130 contact_name = contact_name,
124 131 contact_email = contact_email,
125 132 bug_tracker = bug_tracker,
126 133 crash_report_fname = self.crash_report_fname)
127 134
128 135
129 136 def __call__(self, etype, evalue, etb):
130 137 """Handle an exception, call for compatible with sys.excepthook"""
131 138
132 139 # do not allow the crash handler to be called twice without reinstalling it
133 140 # this prevents unlikely errors in the crash handling from entering an
134 141 # infinite loop.
135 142 sys.excepthook = sys.__excepthook__
136 143
137 144 # Report tracebacks shouldn't use color in general (safer for users)
138 145 color_scheme = 'NoColor'
139 146
140 147 # Use this ONLY for developer debugging (keep commented out for release)
141 148 #color_scheme = 'Linux' # dbg
142 149 try:
143 150 rptdir = self.app.ipython_dir
144 151 except:
145 152 rptdir = os.getcwd()
146 153 if rptdir is None or not os.path.isdir(rptdir):
147 154 rptdir = os.getcwd()
148 155 report_name = os.path.join(rptdir,self.crash_report_fname)
149 156 # write the report filename into the instance dict so it can get
150 157 # properly expanded out in the user message template
151 158 self.crash_report_fname = report_name
152 159 self.info['crash_report_fname'] = report_name
153 160 TBhandler = ultratb.VerboseTB(
154 161 color_scheme=color_scheme,
155 162 long_header=1,
156 163 call_pdb=self.call_pdb,
157 164 )
158 165 if self.call_pdb:
159 166 TBhandler(etype,evalue,etb)
160 167 return
161 168 else:
162 169 traceback = TBhandler.text(etype,evalue,etb,context=31)
163 170
164 171 # print traceback to screen
165 172 if self.show_crash_traceback:
166 173 print(traceback, file=sys.stderr)
167 174
168 175 # and generate a complete report on disk
169 176 try:
170 177 report = open(report_name,'w')
171 178 except:
172 179 print('Could not create crash report on disk.', file=sys.stderr)
173 180 return
174 181
175 182 # Inform user on stderr of what happened
176 183 print('\n'+'*'*70+'\n', file=sys.stderr)
177 184 print(self.message_template.format(**self.info), file=sys.stderr)
178 185
179 186 # Construct report on disk
180 187 report.write(self.make_report(traceback))
181 188 report.close()
182 189 input("Hit <Enter> to quit (your terminal may close):")
183 190
184 191 def make_report(self,traceback):
185 192 """Return a string containing a crash report."""
186 193
187 194 sec_sep = self.section_sep
188 195
189 196 report = ['*'*75+'\n\n'+'IPython post-mortem report\n\n']
190 197 rpt_add = report.append
191 198 rpt_add(sys_info())
192 199
193 200 try:
194 201 config = pformat(self.app.config)
195 202 rpt_add(sec_sep)
196 203 rpt_add('Application name: %s\n\n' % self.app_name)
197 204 rpt_add('Current user configuration structure:\n\n')
198 205 rpt_add(config)
199 206 except:
200 207 pass
201 208 rpt_add(sec_sep+'Crash traceback:\n\n' + traceback)
202 209
203 210 return ''.join(report)
204 211
205 212
206 213 def crash_handler_lite(etype, evalue, tb):
207 214 """a light excepthook, adding a small message to the usual traceback"""
208 215 traceback.print_exception(etype, evalue, tb)
209 216
210 217 from IPython.core.interactiveshell import InteractiveShell
211 218 if InteractiveShell.initialized():
212 219 # we are in a Shell environment, give %magic example
213 220 config = "%config "
214 221 else:
215 222 # we are not in a shell, show generic config
216 223 config = "c."
217 224 print(_lite_message_template.format(email=author_email, config=config), file=sys.stderr)
218 225
General Comments 0
You need to be logged in to leave comments. Login now