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

Side by Side Diff: breakpad.py

Issue 9178019: Overhaul breakpad to optionally disable output. Add git-cl dcommit unit test. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Created 8 years, 11 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 | « no previous file | gcl.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 """Breakpad for Python.
6 6
7 Sends a notification when a process stops on an exception. 7 Sends a notification when a process stops on an exception.
8 8
9 It is only enabled when all these conditions are met: 9 It is only enabled when all these conditions are met:
10 1. hostname finishes with '.google.com' or 'chromium.org' 10 1. hostname finishes with '.google.com' or 'chromium.org'
(...skipping 24 matching lines...) Expand all
35 35
36 # Skip unit tests and we don't want anything from non-googler. 36 # Skip unit tests and we don't want anything from non-googler.
37 IS_ENABLED = ( 37 IS_ENABLED = (
38 not 'test' in getattr(sys.modules['__main__'], '__file__', '') and 38 not 'test' in getattr(sys.modules['__main__'], '__file__', '') and
39 not 'NO_BREAKPAD' in os.environ and 39 not 'NO_BREAKPAD' in os.environ and
40 _HOST_NAME.endswith(('.google.com', '.chromium.org'))) 40 _HOST_NAME.endswith(('.google.com', '.chromium.org')))
41 41
42 42
43 def post(url, params): 43 def post(url, params):
44 """HTTP POST with timeout when it's supported.""" 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
45 kwargs = {} 48 kwargs = {}
46 if (sys.version_info[0] * 10 + sys.version_info[1]) >= 26: 49 if (sys.version_info[0] * 10 + sys.version_info[1]) >= 26:
47 kwargs['timeout'] = 4 50 kwargs['timeout'] = 4
48 request = urllib2.urlopen(url, urllib.urlencode(params), **kwargs) 51 try:
49 out = request.read() 52 request = urllib2.urlopen(url, urllib.urlencode(params), **kwargs)
50 request.close() 53 out = request.read()
51 return out 54 request.close()
55 return out
56 except IOError:
57 return 'There was a failure while trying to send the stack trace. Too bad.'
52 58
53 59
54 def FormatException(e): 60 def FormatException(e):
55 """Returns a human readable form of an exception. 61 """Returns a human readable form of an exception.
56 62
57 Adds the maximum number of interesting information in the safest way.""" 63 Adds the maximum number of interesting information in the safest way."""
58 try: 64 try:
59 out = repr(e) 65 out = repr(e)
60 except Exception: 66 except Exception:
61 out = '' 67 out = ''
(...skipping 10 matching lines...) Expand all
72 # The web page in some urllib exceptions. 78 # The web page in some urllib exceptions.
73 if hasattr(e, 'read') and callable(e.read): 79 if hasattr(e, 'read') and callable(e.read):
74 out += '\nread(): %s' % e.read() 80 out += '\nread(): %s' % e.read()
75 if hasattr(e, 'info') and callable(e.info): 81 if hasattr(e, 'info') and callable(e.info):
76 out += '\ninfo(): %s' % e.info() 82 out += '\ninfo(): %s' % e.info()
77 except Exception: 83 except Exception:
78 pass 84 pass
79 return out 85 return out
80 86
81 87
82 def SendStack(last_tb, stack, url=None, maxlen=50): 88 def SendStack(last_tb, stack, url=None, maxlen=50, verbose=True):
83 """Sends the stack trace to the breakpad server.""" 89 """Sends the stack trace to the breakpad server."""
84 if not IS_ENABLED: 90 if not IS_ENABLED:
85 # Make sure to not send anything for non googler.
86 return 91 return
87 if not url: 92 def p(o):
88 url = DEFAULT_URL + '/breakpad' 93 if verbose:
89 print 'Sending crash report ...' 94 print(o)
90 try: 95 p('Sending crash report ...')
91 params = { 96 params = {
92 'args': sys.argv, 97 'args': sys.argv,
93 'stack': stack[0:4096], 98 'cwd': os.getcwd(),
94 'user': getpass.getuser(), 99 'exception': FormatException(last_tb),
95 'exception': FormatException(last_tb), 100 'host': _HOST_NAME,
96 'host': _HOST_NAME, 101 'stack': stack[0:4096],
97 'cwd': os.getcwd(), 102 'user': getpass.getuser(),
98 'version': sys.version, 103 'version': sys.version,
99 } 104 }
100 # pylint: disable=W0702 105 p('\n'.join(' %s: %s' % (k, params[k][0:maxlen]) for k in sorted(params)))
101 print('\n'.join(' %s: %s' % (k, params[k][0:maxlen]) 106 p(post(url or DEFAULT_URL + '/breakpad', params))
102 for k in sorted(params)))
103 print(post(url, params))
104 except IOError:
105 print('There was a failure while trying to send the stack trace. Too bad.')
106 107
107 108
108 def SendProfiling(url=None): 109 def SendProfiling(url=None):
109 try: 110 params = {
110 if not url: 111 'argv': ' '.join(sys.argv),
111 url = DEFAULT_URL + '/profiling' 112 # Strip the hostname.
112 params = { 113 'domain': _HOST_NAME.split('.', 1)[-1],
113 'argv': ' '.join(sys.argv), 114 'duration': time.time() - _TIME_STARTED,
114 # Strip the hostname. 115 'platform': sys.platform,
115 'domain': _HOST_NAME.split('.', 1)[-1], 116 }
116 'duration': time.time() - _TIME_STARTED, 117 post(url or DEFAULT_URL + '/profiling', params)
117 'platform': sys.platform,
118 }
119 post(url, params)
120 except IOError:
121 pass
122 118
123 119
124 def CheckForException(): 120 def CheckForException():
125 """Runs at exit. Look if there was an exception active.""" 121 """Runs at exit. Look if there was an exception active."""
126 last_value = getattr(sys, 'last_value', None) 122 last_value = getattr(sys, 'last_value', None)
127 if last_value: 123 if last_value:
128 if not isinstance(last_value, KeyboardInterrupt): 124 if not isinstance(last_value, KeyboardInterrupt):
129 last_tb = getattr(sys, 'last_traceback', None) 125 last_tb = getattr(sys, 'last_traceback', None)
130 if last_tb: 126 if last_tb:
131 SendStack(last_value, ''.join(traceback.format_tb(last_tb))) 127 SendStack(last_value, ''.join(traceback.format_tb(last_tb)))
132 else: 128 else:
133 SendProfiling() 129 SendProfiling()
134 130
135 131
136 def Register(): 132 def Register():
137 """Registers the callback at exit. Calling it multiple times is no-op.""" 133 """Registers the callback at exit. Calling it multiple times is no-op."""
138 global _REGISTERED 134 global _REGISTERED
139 if _REGISTERED: 135 if _REGISTERED:
140 return 136 return
141 _REGISTERED = True 137 _REGISTERED = True
142 atexit.register(CheckForException) 138 atexit.register(CheckForException)
143 139
144 140
145 if IS_ENABLED: 141 if IS_ENABLED:
146 Register() 142 Register()
147 143
148 # Uncomment this line if you want to test it out. 144 # Uncomment this line if you want to test it out.
149 #Register() 145 #Register()
OLDNEW
« no previous file with comments | « no previous file | gcl.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698