| OLD | NEW |
| 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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 'exception': FormatException(last_tb), | 99 'exception': FormatException(last_tb), |
| 100 'host': _HOST_NAME, | 100 'host': _HOST_NAME, |
| 101 'stack': stack[0:4096], | 101 'stack': stack[0:4096], |
| 102 'user': getpass.getuser(), | 102 'user': getpass.getuser(), |
| 103 'version': sys.version, | 103 'version': sys.version, |
| 104 } | 104 } |
| 105 p('\n'.join(' %s: %s' % (k, params[k][0:maxlen]) for k in sorted(params))) | 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)) | 106 p(post(url or DEFAULT_URL + '/breakpad', params)) |
| 107 | 107 |
| 108 | 108 |
| 109 def SendProfiling(url=None): | 109 def SendProfiling(duration, url=None): |
| 110 params = { | 110 params = { |
| 111 'argv': ' '.join(sys.argv), | 111 'argv': ' '.join(sys.argv), |
| 112 # Strip the hostname. | 112 # Strip the hostname. |
| 113 'domain': _HOST_NAME.split('.', 1)[-1], | 113 'domain': _HOST_NAME.split('.', 1)[-1], |
| 114 'duration': time.time() - _TIME_STARTED, | 114 'duration': duration, |
| 115 'platform': sys.platform, | 115 'platform': sys.platform, |
| 116 } | 116 } |
| 117 post(url or DEFAULT_URL + '/profiling', params) | 117 post(url or DEFAULT_URL + '/profiling', params) |
| 118 | 118 |
| 119 | 119 |
| 120 def CheckForException(): | 120 def CheckForException(): |
| 121 """Runs at exit. Look if there was an exception active.""" | 121 """Runs at exit. Look if there was an exception active.""" |
| 122 last_value = getattr(sys, 'last_value', None) | 122 last_value = getattr(sys, 'last_value', None) |
| 123 if last_value: | 123 if last_value: |
| 124 if not isinstance(last_value, KeyboardInterrupt): | 124 if not isinstance(last_value, KeyboardInterrupt): |
| 125 last_tb = getattr(sys, 'last_traceback', None) | 125 last_tb = getattr(sys, 'last_traceback', None) |
| 126 if last_tb: | 126 if last_tb: |
| 127 SendStack(last_value, ''.join(traceback.format_tb(last_tb))) | 127 SendStack(last_value, ''.join(traceback.format_tb(last_tb))) |
| 128 else: | 128 else: |
| 129 SendProfiling() | 129 duration = time.time() - _TIME_STARTED |
| 130 if duration > 90: |
| 131 SendProfiling(duration) |
| 130 | 132 |
| 131 | 133 |
| 132 def Register(): | 134 def Register(): |
| 133 """Registers the callback at exit. Calling it multiple times is no-op.""" | 135 """Registers the callback at exit. Calling it multiple times is no-op.""" |
| 134 global _REGISTERED | 136 global _REGISTERED |
| 135 if _REGISTERED: | 137 if _REGISTERED: |
| 136 return | 138 return |
| 137 _REGISTERED = True | 139 _REGISTERED = True |
| 138 atexit.register(CheckForException) | 140 atexit.register(CheckForException) |
| 139 | 141 |
| 140 | 142 |
| 141 if IS_ENABLED: | 143 if IS_ENABLED: |
| 142 Register() | 144 Register() |
| 143 | 145 |
| 144 # Uncomment this line if you want to test it out. | 146 # Uncomment this line if you want to test it out. |
| 145 #Register() | 147 #Register() |
| OLD | NEW |