/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 bzrlib/crash.py

  • Committer: Richard Wilbur
  • Date: 2016-02-04 19:07:28 UTC
  • mto: This revision was merged to the branch mainline in revision 6618.
  • Revision ID: richard.wilbur@gmail.com-20160204190728-p0zvfii6zase0fw7
Update COPYING.txt from the original http://www.gnu.org/licenses/gpl-2.0.txt  (Only differences were in whitespace.)  Thanks to Petr Stodulka for pointing out the discrepancy.

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
In principle apport can run on any platform though as of Feb 2010 there seem
33
33
to be some portability bugs.
34
34
 
35
 
To force this off in brz turn set APPORT_DISABLE in the environment or
 
35
To force this off in bzr turn set APPORT_DISABLE in the environment or 
36
36
-Dno_apport.
37
37
"""
38
38
 
39
 
# for interactive testing, try the 'brz assert-fail' command
 
39
from __future__ import absolute_import
 
40
 
 
41
# for interactive testing, try the 'bzr assert-fail' command 
40
42
# or see http://code.launchpad.net/~mbp/bzr/bzr-fail
41
43
#
42
44
# to test with apport it's useful to set
43
45
# export APPORT_IGNORE_OBSOLETE_PACKAGES=1
44
46
 
45
 
from io import StringIO
46
47
import os
47
48
import platform
48
49
import pprint
49
50
import sys
50
51
import time
 
52
from StringIO import StringIO
51
53
 
52
 
import breezy
53
 
from . import (
54
 
    bedding,
 
54
import bzrlib
 
55
from bzrlib import (
 
56
    config,
55
57
    debug,
56
58
    osutils,
57
59
    plugin,
61
63
 
62
64
def report_bug(exc_info, stderr):
63
65
    if ('no_apport' in debug.debug_flags) or \
64
 
            os.environ.get('APPORT_DISABLE', None):
 
66
        os.environ.get('APPORT_DISABLE', None):
65
67
        return report_bug_legacy(exc_info, stderr)
66
68
    try:
67
69
        if report_bug_to_apport(exc_info, stderr):
68
70
            # wrote a file; if None then report the old way
69
71
            return
70
 
    except ImportError as e:
 
72
    except ImportError, e:
71
73
        trace.mutter("couldn't find apport bug-reporting library: %s" % e)
72
 
    except Exception as e:
 
74
    except Exception, e:
73
75
        # this should only happen if apport is installed but it didn't
74
76
        # work, eg because of an io error writing the crash file
75
 
        trace.mutter("brz: failed to report crash using apport: %r" % e)
 
77
        trace.mutter("bzr: failed to report crash using apport: %r" % e)
76
78
        trace.log_exception_quietly()
77
79
    return report_bug_legacy(exc_info, stderr)
78
80
 
82
84
    trace.print_exception(exc_info, err_file)
83
85
    err_file.write('\n')
84
86
    import textwrap
85
 
 
86
87
    def print_wrapped(l):
87
 
        err_file.write(textwrap.fill(
88
 
            l, width=78, subsequent_indent='    ') + '\n')
89
 
    print_wrapped('brz %s on python %s (%s)\n' %
90
 
                  (breezy.__version__,
91
 
                   breezy._format_version_tuple(sys.version_info),
92
 
                   platform.platform(aliased=1)))
 
88
        err_file.write(textwrap.fill(l,
 
89
            width=78, subsequent_indent='    ') + '\n')
 
90
    print_wrapped('bzr %s on python %s (%s)\n' % \
 
91
        (bzrlib.__version__,
 
92
        bzrlib._format_version_tuple(sys.version_info),
 
93
        platform.platform(aliased=1)))
93
94
    print_wrapped('arguments: %r\n' % sys.argv)
94
95
    print_wrapped(textwrap.fill(
95
96
        'plugins: ' + plugin.format_concise_plugin_list(),
105
106
        "\n"
106
107
        "*** Bazaar has encountered an internal error.  This probably indicates a\n"
107
108
        "    bug in Bazaar.  You can help us fix it by filing a bug report at\n"
108
 
        "        https://bugs.launchpad.net/brz/+filebug\n"
 
109
        "        https://bugs.launchpad.net/bzr/+filebug\n"
109
110
        "    including this traceback and a description of the problem.\n"
110
111
        )
111
112
 
121
122
    # This import is apparently not used, but we're doing it so that if the
122
123
    # import fails, the exception will be caught at a higher level and we'll
123
124
    # report the error by other means.
124
 
    import apport  # noqa: F401
 
125
    import apport
125
126
 
126
127
    crash_filename = _write_apport_report_to_file(exc_info)
127
128
 
128
129
    if crash_filename is None:
129
130
        stderr.write("\n"
130
 
                     "apport is set to ignore crashes in this version of brz.\n"
131
 
                     )
 
131
            "apport is set to ignore crashes in this version of bzr.\n"
 
132
            )
132
133
    else:
133
134
        trace.print_exception(exc_info, stderr)
134
135
        stderr.write("\n"
135
 
                     "You can report this problem to Bazaar's developers by running\n"
136
 
                     "    apport-bug %s\n"
137
 
                     "if a bug-reporting window does not automatically appear.\n"
138
 
                     % (crash_filename))
 
136
            "You can report this problem to Bazaar's developers by running\n"
 
137
            "    apport-bug %s\n"
 
138
            "if a bug-reporting window does not automatically appear.\n"
 
139
            % (crash_filename))
139
140
        # XXX: on Windows, Mac, and other platforms where we might have the
140
141
        # apport libraries but not have an apport always running, we could
141
142
        # synchronously file now
158
159
    pr.add_user_info()
159
160
 
160
161
    # Package and SourcePackage are needed so that apport will report about even
161
 
    # non-packaged versions of brz; also this reports on their packaged
 
162
    # non-packaged versions of bzr; also this reports on their packaged
162
163
    # dependencies which is useful.
163
 
    pr['SourcePackage'] = 'brz'
164
 
    pr['Package'] = 'brz'
 
164
    pr['SourcePackage'] = 'bzr'
 
165
    pr['Package'] = 'bzr'
165
166
 
166
167
    pr['CommandLine'] = pprint.pformat(sys.argv)
167
 
    pr['BrzVersion'] = breezy.__version__
168
 
    pr['PythonVersion'] = breezy._format_version_tuple(sys.version_info)
 
168
    pr['BzrVersion'] = bzrlib.__version__
 
169
    pr['PythonVersion'] = bzrlib._format_version_tuple(sys.version_info)
169
170
    pr['Platform'] = platform.platform(aliased=1)
170
171
    pr['UserEncoding'] = osutils.get_user_encoding()
171
172
    pr['FileSystemEncoding'] = sys.getfilesystemencoding()
172
173
    pr['Locale'] = os.environ.get('LANG', 'C')
173
 
    pr['BrzPlugins'] = _format_plugin_list()
 
174
    pr['BzrPlugins'] = _format_plugin_list()
174
175
    pr['PythonLoadedModules'] = _format_module_list()
175
 
    pr['BrzDebugFlags'] = pprint.pformat(debug.debug_flags)
 
176
    pr['BzrDebugFlags'] = pprint.pformat(debug.debug_flags)
176
177
 
177
178
    # actually we'd rather file directly against the upstream product, but
178
179
    # apport does seem to count on there being one in there; we might need to
179
180
    # redirect it elsewhere anyhow
180
 
    pr['SourcePackage'] = 'brz'
181
 
    pr['Package'] = 'brz'
 
181
    pr['SourcePackage'] = 'bzr'
 
182
    pr['Package'] = 'bzr'
182
183
 
183
 
    # tell apport to file directly against the brz package using
 
184
    # tell apport to file directly against the bzr package using 
184
185
    # <https://bugs.launchpad.net/bzr/+bug/391015>
185
186
    #
186
187
    # XXX: unfortunately apport may crash later if the crashdb definition
187
188
    # file isn't present
188
 
    pr['CrashDb'] = 'brz'
 
189
    pr['CrashDb'] = 'bzr'
189
190
 
190
191
    tb_file = StringIO()
191
192
    traceback.print_exception(exc_type, exc_object, exc_tb, file=tb_file)
193
194
 
194
195
    _attach_log_tail(pr)
195
196
 
196
 
    # We want to use the 'brz' crashdb so that it gets sent directly upstream,
 
197
    # We want to use the 'bzr' crashdb so that it gets sent directly upstream,
197
198
    # which is a reasonable default for most internal errors.  However, if we
198
199
    # set it here then apport will crash later if it doesn't know about that
199
 
    # crashdb.  Instead, we rely on the brz package installing both a
 
200
    # crashdb.  Instead, we rely on the bzr package installing both a
200
201
    # source hook telling crashes to go to this crashdb, and a crashdb
201
202
    # configuration describing it.
202
203
 
203
204
    # these may contain some sensitive info (smtp_passwords)
204
205
    # TODO: strip that out and attach the rest
205
206
    #
206
 
    # attach_file_if_exists(report,
207
 
    #   os.path.join(dot_brz, 'breezy.conf', 'BrzConfig')
208
 
    # attach_file_if_exists(report,
209
 
    #   os.path.join(dot_brz, 'locations.conf', 'BrzLocations')
210
 
 
 
207
    #attach_file_if_exists(report,
 
208
    #   os.path.join(dot_bzr, 'bazaar.conf', 'BzrConfig')
 
209
    #attach_file_if_exists(report,
 
210
    #   os.path.join(dot_bzr, 'locations.conf', 'BzrLocations')
 
211
    
211
212
    # strip username, hostname, etc
212
213
    pr.anonymize()
213
214
 
223
224
 
224
225
def _attach_log_tail(pr):
225
226
    try:
226
 
        brz_log = open(trace._get_brz_log_filename(), 'rt')
227
 
    except (IOError, OSError) as e:
228
 
        pr['BrzLogTail'] = repr(e)
 
227
        bzr_log = open(trace._get_bzr_log_filename(), 'rt')
 
228
    except (IOError, OSError), e:
 
229
        pr['BzrLogTail'] = repr(e)
229
230
        return
230
231
    try:
231
 
        lines = brz_log.readlines()
232
 
        pr['BrzLogTail'] = ''.join(lines[-40:])
 
232
        lines = bzr_log.readlines()
 
233
        pr['BzrLogTail'] = ''.join(lines[-40:])
233
234
    finally:
234
 
        brz_log.close()
 
235
        bzr_log.close()
235
236
 
236
237
 
237
238
def _open_crash_file():
238
 
    crash_dir = bedding.crash_dir()
 
239
    crash_dir = config.crash_dir()
239
240
    if not osutils.isdir(crash_dir):
240
241
        # on unix this should be /var/crash and should already exist; on
241
242
        # Windows or if it's manually configured it might need to be created,
242
243
        # and then it should be private
243
 
        os.makedirs(crash_dir, mode=0o600)
 
244
        os.makedirs(crash_dir, mode=0600)
244
245
    date_string = time.strftime('%Y-%m-%dT%H:%M', time.gmtime())
245
246
    # XXX: getuid doesn't work on win32, but the crash directory is per-user
246
247
    if sys.platform == 'win32':
249
250
        user_part = '.%d' % os.getuid()
250
251
    filename = osutils.pathjoin(
251
252
        crash_dir,
252
 
        'brz%s.%s.crash' % (
 
253
        'bzr%s.%s.crash' % (
253
254
            user_part,
254
255
            date_string))
255
256
    # be careful here that people can't play tmp-type symlink mischief in the
256
257
    # world-writable directory
257
258
    return filename, os.fdopen(
258
 
        os.open(filename,
259
 
                os.O_WRONLY | os.O_CREAT | os.O_EXCL,
260
 
                0o600),
 
259
        os.open(filename, 
 
260
            os.O_WRONLY|os.O_CREAT|os.O_EXCL,
 
261
            0600),
261
262
        'wb')
262
263
 
263
264