~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/crash.py

  • Committer: Jelmer Vernooij
  • Date: 2011-12-14 12:15:44 UTC
  • mto: This revision was merged to the branch mainline in revision 6365.
  • Revision ID: jelmer@samba.org-20111214121544-v07cbvmi30re6q7w
s/NoVfsCalls/ContainsNoVfsCalls/.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2009, 2010 Canonical Ltd
 
1
# Copyright (C) 2009-2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
20
20
A crash is an exception propagated up almost to the top level of Bazaar.
21
21
 
22
22
If we have apport <https://launchpad.net/apport/>, we store a report of the
23
 
crash using apport into it's /var/crash spool directory, from where the user
 
23
crash using apport into its /var/crash spool directory, from where the user
24
24
can either manually send it to Launchpad.  In some cases (at least Ubuntu
25
25
development releases), Apport may pop up a window asking if they want
26
26
to send it.
33
33
In principle apport can run on any platform though as of Feb 2010 there seem
34
34
to be some portability bugs.
35
35
 
36
 
To force this off in bzr turn set APPORT_DISBLE in the environment or 
 
36
To force this off in bzr turn set APPORT_DISABLE in the environment or 
37
37
-Dno_apport.
38
38
"""
39
39
 
70
70
            return
71
71
    except ImportError, e:
72
72
        trace.mutter("couldn't find apport bug-reporting library: %s" % e)
73
 
        pass
74
73
    except Exception, e:
75
74
        # this should only happen if apport is installed but it didn't
76
75
        # work, eg because of an io error writing the crash file
77
 
        stderr.write("bzr: failed to report crash using apport:\n "
78
 
            "    %r\n" % e)
79
 
        pass
 
76
        trace.mutter("bzr: failed to report crash using apport: %r" % e)
 
77
        trace.log_exception_quietly()
80
78
    return report_bug_legacy(exc_info, stderr)
81
79
 
82
80
 
84
82
    """Report a bug by just printing a message to the user."""
85
83
    trace.print_exception(exc_info, err_file)
86
84
    err_file.write('\n')
87
 
    err_file.write('bzr %s on python %s (%s)\n' % \
88
 
                       (bzrlib.__version__,
89
 
                        bzrlib._format_version_tuple(sys.version_info),
90
 
                        platform.platform(aliased=1)))
91
 
    err_file.write('arguments: %r\n' % sys.argv)
92
 
    err_file.write(
 
85
    import textwrap
 
86
    def print_wrapped(l):
 
87
        err_file.write(textwrap.fill(l,
 
88
            width=78, subsequent_indent='    ') + '\n')
 
89
    print_wrapped('bzr %s on python %s (%s)\n' % \
 
90
        (bzrlib.__version__,
 
91
        bzrlib._format_version_tuple(sys.version_info),
 
92
        platform.platform(aliased=1)))
 
93
    print_wrapped('arguments: %r\n' % sys.argv)
 
94
    print_wrapped(textwrap.fill(
 
95
        'plugins: ' + plugin.format_concise_plugin_list(),
 
96
        width=78,
 
97
        subsequent_indent='    ',
 
98
        ) + '\n')
 
99
    print_wrapped(
93
100
        'encoding: %r, fsenc: %r, lang: %r\n' % (
94
101
            osutils.get_user_encoding(), sys.getfilesystemencoding(),
95
102
            os.environ.get('LANG')))
96
 
    err_file.write("plugins:\n")
97
 
    err_file.write(_format_plugin_list())
 
103
    # We used to show all the plugins here, but it's too verbose.
98
104
    err_file.write(
99
 
        "\n\n"
 
105
        "\n"
100
106
        "*** Bazaar has encountered an internal error.  This probably indicates a\n"
101
107
        "    bug in Bazaar.  You can help us fix it by filing a bug report at\n"
102
108
        "        https://bugs.launchpad.net/bzr/+filebug\n"
112
118
    # this function is based on apport_package_hook.py, but omitting some of the
113
119
    # Ubuntu-specific policy about what to report and when
114
120
 
115
 
    # if the import fails, the exception will be caught at a higher level and
116
 
    # we'll report the error by other means
 
121
    # This import is apparently not used, but we're doing it so that if the
 
122
    # import fails, the exception will be caught at a higher level and we'll
 
123
    # report the error by other means.
117
124
    import apport
118
125
 
119
126
    crash_filename = _write_apport_report_to_file(exc_info)
143
150
    exc_type, exc_object, exc_tb = exc_info
144
151
 
145
152
    pr = Report()
146
 
    # add_proc_info gets the executable and interpreter path, which is needed,
147
 
    # plus some less useful stuff like the memory map
 
153
    # add_proc_info sets the ExecutablePath, InterpreterPath, etc.
148
154
    pr.add_proc_info()
 
155
    # It also adds ProcMaps which for us is rarely useful and mostly noise, so
 
156
    # let's remove it.
 
157
    del pr['ProcMaps']
149
158
    pr.add_user_info()
150
159
 
151
160
    # Package and SourcePackage are needed so that apport will report about even
165
174
    pr['PythonLoadedModules'] = _format_module_list()
166
175
    pr['BzrDebugFlags'] = pprint.pformat(debug.debug_flags)
167
176
 
 
177
    # actually we'd rather file directly against the upstream product, but
 
178
    # apport does seem to count on there being one in there; we might need to
 
179
    # redirect it elsewhere anyhow
 
180
    pr['SourcePackage'] = 'bzr'
 
181
    pr['Package'] = 'bzr'
 
182
 
 
183
    # tell apport to file directly against the bzr package using 
 
184
    # <https://bugs.launchpad.net/bzr/+bug/391015>
 
185
    #
 
186
    # XXX: unfortunately apport may crash later if the crashdb definition
 
187
    # file isn't present
 
188
    pr['CrashDb'] = 'bzr'
 
189
 
168
190
    tb_file = StringIO()
169
191
    traceback.print_exception(exc_type, exc_object, exc_tb, file=tb_file)
170
192
    pr['Traceback'] = tb_file.getvalue()
240
262
 
241
263
 
242
264
def _format_plugin_list():
243
 
    plugin_lines = []
244
 
    for name, a_plugin in sorted(plugin.plugins().items()):
245
 
        plugin_lines.append("  %-20s %s [%s]" %
246
 
            (name, a_plugin.path(), a_plugin.__version__))
247
 
    return '\n'.join(plugin_lines)
 
265
    return ''.join(plugin.describe_plugins(show_paths=True))
248
266
 
249
267
 
250
268
def _format_module_list():