OLD | NEW |
1 # Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2009 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 |
| 9 It is only enabled when all these conditions are met: |
| 10 1. hostname finishes with '.google.com' |
| 11 2. main module name doesn't contain the word 'test' |
| 12 3. no NO_BREAKPAD environment variable is defined |
| 13 """ |
8 | 14 |
9 import atexit | 15 import atexit |
10 import getpass | 16 import getpass |
| 17 import os |
11 import urllib | 18 import urllib |
12 import traceback | 19 import traceback |
13 import socket | 20 import socket |
14 import sys | 21 import sys |
15 | 22 |
16 | 23 |
17 # Configure these values. | 24 # Configure these values. |
18 DEFAULT_URL = 'https://chromium-status.appspot.com/breakpad' | 25 DEFAULT_URL = 'https://chromium-status.appspot.com/breakpad' |
19 | 26 |
20 _REGISTERED = False | 27 _REGISTERED = False |
21 | 28 |
22 | 29 |
23 def SendStack(last_tb, stack, url=None): | 30 def SendStack(last_tb, stack, url=None): |
24 """Sends the stack trace to the breakpad server.""" | 31 """Sends the stack trace to the breakpad server.""" |
25 if not url: | 32 if not url: |
26 url = DEFAULT_URL | 33 url = DEFAULT_URL |
27 print 'Sending crash report ...' | 34 print 'Sending crash report ...' |
28 try: | 35 try: |
29 params = { | 36 params = { |
30 'args': sys.argv, | 37 'args': sys.argv, |
31 'stack': stack, | 38 'stack': stack, |
32 'user': getpass.getuser(), | 39 'user': getpass.getuser(), |
33 'exception': last_tb, | 40 'exception': last_tb, |
34 'host': socket.getfqdn(), | 41 'host': socket.getfqdn(), |
35 } | 42 } |
| 43 try: |
| 44 # That may not always work. |
| 45 params['exception'] = str(last_tb) |
| 46 except: |
| 47 pass |
36 request = urllib.urlopen(url, urllib.urlencode(params)) | 48 request = urllib.urlopen(url, urllib.urlencode(params)) |
37 print request.read() | 49 print request.read() |
38 request.close() | 50 request.close() |
39 except IOError: | 51 except IOError: |
40 print('There was a failure while trying to send the stack trace. Too bad.') | 52 print('There was a failure while trying to send the stack trace. Too bad.') |
41 | 53 |
42 | 54 |
43 def CheckForException(): | 55 def CheckForException(): |
44 """Runs at exit. Look if there was an exception active.""" | 56 """Runs at exit. Look if there was an exception active.""" |
45 last_value = getattr(sys, 'last_value', None) | 57 last_value = getattr(sys, 'last_value', None) |
46 if last_value and not isinstance(last_value, KeyboardInterrupt): | 58 if last_value and not isinstance(last_value, KeyboardInterrupt): |
47 last_tb = getattr(sys, 'last_traceback', None) | 59 last_tb = getattr(sys, 'last_traceback', None) |
48 if last_tb: | 60 if last_tb: |
49 SendStack(repr(last_value), ''.join(traceback.format_tb(last_tb))) | 61 SendStack(repr(last_value), ''.join(traceback.format_tb(last_tb))) |
50 | 62 |
51 | 63 |
52 def Register(): | 64 def Register(): |
53 """Registers the callback at exit. Calling it multiple times is no-op.""" | 65 """Registers the callback at exit. Calling it multiple times is no-op.""" |
54 global _REGISTERED | 66 global _REGISTERED |
55 if _REGISTERED: | 67 if _REGISTERED: |
56 return | 68 return |
57 _REGISTERED = True | 69 _REGISTERED = True |
58 atexit.register(CheckForException) | 70 atexit.register(CheckForException) |
59 | 71 |
60 | 72 |
61 # Skip unit tests and we don't want anything from non-googler. | 73 # Skip unit tests and we don't want anything from non-googler. |
62 if (not 'test' in sys.modules['__main__'].__file__ and | 74 if (not 'test' in sys.modules['__main__'].__file__ and |
63 socket.getfqdn().endswith('.google.com')): | 75 socket.getfqdn().endswith('.google.com') and |
| 76 not 'NO_BREAKPAD' in os.environ): |
64 Register() | 77 Register() |
65 | 78 |
66 # Uncomment this line if you want to test it out. | 79 # Uncomment this line if you want to test it out. |
67 #Register() | 80 #Register() |
OLD | NEW |