| 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 | 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' | 10 1. hostname finishes with '.google.com' |
| 11 2. main module name doesn't contain the word 'test' | 11 2. main module name doesn't contain the word 'test' |
| 12 3. no NO_BREAKPAD environment variable is defined | 12 3. no NO_BREAKPAD environment variable is defined |
| 13 """ | 13 """ |
| 14 | 14 |
| 15 import atexit | 15 import atexit |
| 16 import getpass | 16 import getpass |
| 17 import os | 17 import os |
| 18 import urllib | 18 import urllib |
| 19 import traceback | 19 import traceback |
| 20 import socket | 20 import socket |
| 21 import sys | 21 import sys |
| 22 | 22 |
| 23 | 23 |
| 24 # Configure these values. | 24 # Configure these values. |
| 25 DEFAULT_URL = 'https://chromium-status.appspot.com/breakpad' | 25 DEFAULT_URL = 'https://chromium-status.appspot.com/breakpad' |
| 26 | 26 |
| 27 _REGISTERED = False | 27 _REGISTERED = False |
| 28 | 28 |
| 29 | 29 |
| 30 def FormatException(e): |
| 31 """Returns a human readable form of an exception. |
| 32 |
| 33 Adds the maximum number of interesting information in the safest way.""" |
| 34 try: |
| 35 out = repr(e) |
| 36 except Exception: |
| 37 out = '' |
| 38 try: |
| 39 out = str(e) |
| 40 if isinstance(e, Exception): |
| 41 # urllib exceptions, usually the HTTP headers. |
| 42 if hasattr(e, 'headers'): |
| 43 out += '\nHeaders: %s' % e.headers |
| 44 if hasattr(e, 'url'): |
| 45 out += '\nUrl: %s' % e.url |
| 46 if hasattr(e, 'msg'): |
| 47 out += '\nMsg: %s' % e.msg |
| 48 # The web page in some urllib exceptions. |
| 49 if hasattr(e, 'read') and callable(e.read): |
| 50 out += '\nread(): %s' % e.read() |
| 51 if hasattr(e, 'info') and callable(e.info): |
| 52 out += '\ninfo(): %s' % e.info() |
| 53 except Exception: |
| 54 pass |
| 55 return out |
| 56 |
| 57 |
| 30 def SendStack(last_tb, stack, url=None): | 58 def SendStack(last_tb, stack, url=None): |
| 31 """Sends the stack trace to the breakpad server.""" | 59 """Sends the stack trace to the breakpad server.""" |
| 32 if not url: | 60 if not url: |
| 33 url = DEFAULT_URL | 61 url = DEFAULT_URL |
| 34 print 'Sending crash report ...' | 62 print 'Sending crash report ...' |
| 35 try: | 63 try: |
| 36 params = { | 64 params = { |
| 37 'args': sys.argv, | 65 'args': sys.argv, |
| 38 'stack': stack, | 66 'stack': stack[0:4096], |
| 39 'user': getpass.getuser(), | 67 'user': getpass.getuser(), |
| 40 'exception': last_tb, | 68 'exception': FormatException(last_tb), |
| 41 'host': socket.getfqdn(), | 69 'host': socket.getfqdn(), |
| 42 'cwd': os.getcwd(), | 70 'cwd': os.getcwd(), |
| 43 } | 71 } |
| 44 # No exception type(s) specified | |
| 45 # pylint: disable=W0702 | 72 # pylint: disable=W0702 |
| 46 try: | |
| 47 # That may not always work. | |
| 48 params['exception'] = str(last_tb) | |
| 49 except: | |
| 50 pass | |
| 51 print('\n'.join(' %s: %s' % (k, v[0:50]) for k, v in params.iteritems())) | 73 print('\n'.join(' %s: %s' % (k, v[0:50]) for k, v in params.iteritems())) |
| 52 request = urllib.urlopen(url, urllib.urlencode(params)) | 74 request = urllib.urlopen(url, urllib.urlencode(params)) |
| 53 print(request.read()) | 75 print(request.read()) |
| 54 request.close() | 76 request.close() |
| 55 except IOError: | 77 except IOError: |
| 56 print('There was a failure while trying to send the stack trace. Too bad.') | 78 print('There was a failure while trying to send the stack trace. Too bad.') |
| 57 | 79 |
| 58 | 80 |
| 59 def CheckForException(): | 81 def CheckForException(): |
| 60 """Runs at exit. Look if there was an exception active.""" | 82 """Runs at exit. Look if there was an exception active.""" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 76 | 98 |
| 77 # Skip unit tests and we don't want anything from non-googler. | 99 # Skip unit tests and we don't want anything from non-googler. |
| 78 if (not 'test' in sys.modules['__main__'].__file__ and | 100 if (not 'test' in sys.modules['__main__'].__file__ and |
| 79 not 'NO_BREAKPAD' in os.environ and | 101 not 'NO_BREAKPAD' in os.environ and |
| 80 (socket.getfqdn().endswith('.google.com') or | 102 (socket.getfqdn().endswith('.google.com') or |
| 81 socket.getfqdn().endswith('.chromium.org'))): | 103 socket.getfqdn().endswith('.chromium.org'))): |
| 82 Register() | 104 Register() |
| 83 | 105 |
| 84 # Uncomment this line if you want to test it out. | 106 # Uncomment this line if you want to test it out. |
| 85 #Register() | 107 #Register() |
| OLD | NEW |