Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1166)

Side by Side Diff: breakpad.py

Issue 1687923002: Finally get rid of depot_tools' breakpad. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: add no-op breakpad.py Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « apply_issue.py ('k') | commit_queue.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Breakpad for Python. 5 """This file remains here because of multiple find_depot_tools.py scripts
6 that attempt to import it as a way to find depot_tools.
6 7
7 Sends a notification when a process stops on an exception. 8 See also:
8 9 * http://crbug.com/585837
9 It is only enabled when all these conditions are met: 10 * Example of find_depot_tools in build repo:
10 1. hostname finishes with '.google.com' or 'chromium.org' 11 https://chromium.googlesource.com/chromium/tools/build/+/2680bd4/scripts/common/ find_depot_tools.py
11 2. main module name doesn't contain the word 'test'
12 3. no NO_BREAKPAD environment variable is defined
13 """ 12 """
14
15 import atexit
16 import getpass
17 import os
18 import socket
19 import sys
20 import time
21 import traceback
22 import urllib
23 import urllib2
24
25
26 # Configure these values.
27 DEFAULT_URL = 'https://chromium-status.appspot.com'
28
29 # Global variable to prevent double registration.
30 _REGISTERED = False
31
32 _TIME_STARTED = time.time()
33
34 _HOST_NAME = socket.getfqdn()
35
36 # Skip unit tests and we don't want anything from non-googler.
37 IS_ENABLED = (
38 not 'test' in getattr(sys.modules['__main__'], '__file__', '') and
39 not 'NO_BREAKPAD' in os.environ and
40 _HOST_NAME.endswith(('.google.com', '.chromium.org')))
41
42
43 def post(url, params):
44 """HTTP POST with timeout when it's supported."""
45 if not IS_ENABLED:
46 # Make sure to not send anything for non googler.
47 return
48 kwargs = {}
49 if (sys.version_info[0] * 10 + sys.version_info[1]) >= 26:
50 kwargs['timeout'] = 4
51 try:
52 request = urllib2.urlopen(url, urllib.urlencode(params), **kwargs)
53 out = request.read()
54 request.close()
55 return out
56 except IOError:
57 return 'There was a failure while trying to send the stack trace. Too bad.'
58
59
60 def FormatException(e):
61 """Returns a human readable form of an exception.
62
63 Adds the maximum number of interesting information in the safest way."""
64 try:
65 out = repr(e)
66 except Exception:
67 out = ''
68 try:
69 out = str(e)
70 if isinstance(e, Exception):
71 # urllib exceptions, usually the HTTP headers.
72 if hasattr(e, 'headers'):
73 out += '\nHeaders: %s' % e.headers
74 if hasattr(e, 'url'):
75 out += '\nUrl: %s' % e.url
76 if hasattr(e, 'msg'):
77 out += '\nMsg: %s' % e.msg
78 # The web page in some urllib exceptions.
79 if hasattr(e, 'read') and callable(e.read):
80 out += '\nread(): %s' % e.read()
81 if hasattr(e, 'info') and callable(e.info):
82 out += '\ninfo(): %s' % e.info()
83 except Exception:
84 pass
85 return out
86
87
88 def SendStack(last_tb, stack, url=None, maxlen=50, verbose=True):
89 """Sends the stack trace to the breakpad server."""
90 if not IS_ENABLED:
91 return
92 def p(o):
93 if verbose:
94 print(o)
95 p('Sending crash report ...')
96 params = {
97 'args': sys.argv,
98 'cwd': os.getcwd(),
99 'exception': FormatException(last_tb),
100 'host': _HOST_NAME,
101 'stack': stack[0:4096],
102 'user': getpass.getuser(),
103 'version': sys.version,
104 }
105 p('\n'.join(' %s: %s' % (k, params[k][0:maxlen]) for k in sorted(params)))
106 p(post(url or DEFAULT_URL + '/breakpad', params))
107
108
109 def SendProfiling(duration, url=None):
110 params = {
111 'argv': ' '.join(sys.argv),
112 # Strip the hostname.
113 'domain': _HOST_NAME.split('.', 1)[-1],
114 'duration': duration,
115 'platform': sys.platform,
116 }
117 post(url or DEFAULT_URL + '/profiling', params)
118
119
120 def CheckForException():
121 """Runs at exit. Look if there was an exception active."""
122 last_value = getattr(sys, 'last_value', None)
123 if last_value:
124 if not isinstance(last_value, KeyboardInterrupt):
125 last_tb = getattr(sys, 'last_traceback', None)
126 if last_tb:
127 SendStack(last_value, ''.join(traceback.format_tb(last_tb)))
128 else:
129 duration = time.time() - _TIME_STARTED
130 if duration > 90:
131 SendProfiling(duration)
132
133
134 def Register():
135 """Registers the callback at exit. Calling it multiple times is no-op."""
136 global _REGISTERED
137 if _REGISTERED:
138 return
139 _REGISTERED = True
140 atexit.register(CheckForException)
141
142
143 if IS_ENABLED:
144 Register()
145
146 # Uncomment this line if you want to test it out.
147 #Register()
OLDNEW
« no previous file with comments | « apply_issue.py ('k') | commit_queue.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698