/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/crash.py

  • Committer: Jelmer Vernooij
  • Date: 2017-06-10 16:40:42 UTC
  • mfrom: (6653.6.7 rename-controldir)
  • mto: This revision was merged to the branch mainline in revision 6690.
  • Revision ID: jelmer@jelmer.uk-20170610164042-zrxqgy2htyduvke2
MergeĀ rename-controldirĀ branch.

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
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
 
 
18
17
"""Handling and reporting crashes.
19
18
 
20
19
A crash is an exception propagated up almost to the top level of Bazaar.
21
20
 
22
21
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
 
22
crash using apport into its /var/crash spool directory, from where the user
24
23
can either manually send it to Launchpad.  In some cases (at least Ubuntu
25
24
development releases), Apport may pop up a window asking if they want
26
25
to send it.
37
36
-Dno_apport.
38
37
"""
39
38
 
 
39
from __future__ import absolute_import
 
40
 
40
41
# for interactive testing, try the 'bzr assert-fail' command 
41
42
# or see http://code.launchpad.net/~mbp/bzr/bzr-fail
42
43
#
48
49
import pprint
49
50
import sys
50
51
import time
51
 
from StringIO import StringIO
52
52
 
53
 
import bzrlib
54
 
from bzrlib import (
 
53
import breezy
 
54
from . import (
55
55
    config,
56
56
    debug,
57
57
    osutils,
58
58
    plugin,
59
59
    trace,
60
60
    )
 
61
from .sixish import (
 
62
    StringIO,
 
63
    )
61
64
 
62
65
 
63
66
def report_bug(exc_info, stderr):
68
71
        if report_bug_to_apport(exc_info, stderr):
69
72
            # wrote a file; if None then report the old way
70
73
            return
71
 
    except ImportError, e:
 
74
    except ImportError as e:
72
75
        trace.mutter("couldn't find apport bug-reporting library: %s" % e)
73
 
        pass
74
 
    except Exception, e:
 
76
    except Exception as e:
75
77
        # this should only happen if apport is installed but it didn't
76
78
        # 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
 
79
        trace.mutter("bzr: failed to report crash using apport: %r" % e)
 
80
        trace.log_exception_quietly()
80
81
    return report_bug_legacy(exc_info, stderr)
81
82
 
82
83
 
84
85
    """Report a bug by just printing a message to the user."""
85
86
    trace.print_exception(exc_info, err_file)
86
87
    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(
 
88
    import textwrap
 
89
    def print_wrapped(l):
 
90
        err_file.write(textwrap.fill(l,
 
91
            width=78, subsequent_indent='    ') + '\n')
 
92
    print_wrapped('bzr %s on python %s (%s)\n' % \
 
93
        (breezy.__version__,
 
94
        breezy._format_version_tuple(sys.version_info),
 
95
        platform.platform(aliased=1)))
 
96
    print_wrapped('arguments: %r\n' % sys.argv)
 
97
    print_wrapped(textwrap.fill(
 
98
        'plugins: ' + plugin.format_concise_plugin_list(),
 
99
        width=78,
 
100
        subsequent_indent='    ',
 
101
        ) + '\n')
 
102
    print_wrapped(
93
103
        'encoding: %r, fsenc: %r, lang: %r\n' % (
94
104
            osutils.get_user_encoding(), sys.getfilesystemencoding(),
95
105
            os.environ.get('LANG')))
96
 
    err_file.write("plugins:\n")
97
 
    err_file.write(_format_plugin_list())
 
106
    # We used to show all the plugins here, but it's too verbose.
98
107
    err_file.write(
99
 
        "\n\n"
 
108
        "\n"
100
109
        "*** Bazaar has encountered an internal error.  This probably indicates a\n"
101
110
        "    bug in Bazaar.  You can help us fix it by filing a bug report at\n"
102
111
        "        https://bugs.launchpad.net/bzr/+filebug\n"
112
121
    # this function is based on apport_package_hook.py, but omitting some of the
113
122
    # Ubuntu-specific policy about what to report and when
114
123
 
115
 
    # if the import fails, the exception will be caught at a higher level and
116
 
    # we'll report the error by other means
 
124
    # This import is apparently not used, but we're doing it so that if the
 
125
    # import fails, the exception will be caught at a higher level and we'll
 
126
    # report the error by other means.
117
127
    import apport
118
128
 
119
129
    crash_filename = _write_apport_report_to_file(exc_info)
143
153
    exc_type, exc_object, exc_tb = exc_info
144
154
 
145
155
    pr = Report()
146
 
    # add_proc_info gives you the memory map of the process, which is not so
147
 
    # useful for Bazaar but does tell you what binary libraries are loaded.
148
 
    # More importantly it sets the ExecutablePath, InterpreterPath, etc.
 
156
    # add_proc_info sets the ExecutablePath, InterpreterPath, etc.
149
157
    pr.add_proc_info()
 
158
    # It also adds ProcMaps which for us is rarely useful and mostly noise, so
 
159
    # let's remove it.
 
160
    del pr['ProcMaps']
150
161
    pr.add_user_info()
151
162
 
152
163
    # Package and SourcePackage are needed so that apport will report about even
156
167
    pr['Package'] = 'bzr'
157
168
 
158
169
    pr['CommandLine'] = pprint.pformat(sys.argv)
159
 
    pr['BzrVersion'] = bzrlib.__version__
160
 
    pr['PythonVersion'] = bzrlib._format_version_tuple(sys.version_info)
 
170
    pr['BzrVersion'] = breezy.__version__
 
171
    pr['PythonVersion'] = breezy._format_version_tuple(sys.version_info)
161
172
    pr['Platform'] = platform.platform(aliased=1)
162
173
    pr['UserEncoding'] = osutils.get_user_encoding()
163
174
    pr['FileSystemEncoding'] = sys.getfilesystemencoding()
164
 
    pr['Locale'] = os.environ.get('LANG')
 
175
    pr['Locale'] = os.environ.get('LANG', 'C')
165
176
    pr['BzrPlugins'] = _format_plugin_list()
166
177
    pr['PythonLoadedModules'] = _format_module_list()
167
178
    pr['BzrDebugFlags'] = pprint.pformat(debug.debug_flags)
173
184
    pr['Package'] = 'bzr'
174
185
 
175
186
    # tell apport to file directly against the bzr package using 
176
 
    # <https://bugs.edge.launchpad.net/bzr/+bug/391015>
 
187
    # <https://bugs.launchpad.net/bzr/+bug/391015>
177
188
    #
178
189
    # XXX: unfortunately apport may crash later if the crashdb definition
179
190
    # file isn't present
215
226
 
216
227
def _attach_log_tail(pr):
217
228
    try:
218
 
        bzr_log = open(trace._get_bzr_log_filename(), 'rt')
219
 
    except (IOError, OSError), e:
 
229
        bzr_log = open(trace._get_brz_log_filename(), 'rt')
 
230
    except (IOError, OSError) as e:
220
231
        pr['BzrLogTail'] = repr(e)
221
232
        return
222
233
    try:
232
243
        # on unix this should be /var/crash and should already exist; on
233
244
        # Windows or if it's manually configured it might need to be created,
234
245
        # and then it should be private
235
 
        os.makedirs(crash_dir, mode=0600)
236
 
    date_string = time.strftime('%Y-%m-%dT%H:%M', time.gmtime())
 
246
        os.makedirs(crash_dir, mode=0o600)
 
247
    date_string = time.strftime('%Y-%m-%dT%H:%M', osutils.gmtime())
237
248
    # XXX: getuid doesn't work on win32, but the crash directory is per-user
238
249
    if sys.platform == 'win32':
239
250
        user_part = ''
249
260
    return filename, os.fdopen(
250
261
        os.open(filename, 
251
262
            os.O_WRONLY|os.O_CREAT|os.O_EXCL,
252
 
            0600),
253
 
        'w')
 
263
            0o600),
 
264
        'wb')
254
265
 
255
266
 
256
267
def _format_plugin_list():
257
 
    plugin_lines = []
258
 
    for name, a_plugin in sorted(plugin.plugins().items()):
259
 
        plugin_lines.append("  %-20s %s [%s]" %
260
 
            (name, a_plugin.path(), a_plugin.__version__))
261
 
    return '\n'.join(plugin_lines)
 
268
    return ''.join(plugin.describe_plugins(show_paths=True))
262
269
 
263
270
 
264
271
def _format_module_list():