breakpad.py 2.2 KB

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