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

Side by Side Diff: tools/utils.py

Issue 2713193002: Add more debugging support to coredump archiving code (Closed)
Patch Set: fix long line, fix win part Created 3 years, 10 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
« no previous file with comments | « no previous file | no next file » | 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 Dart project authors. Please see the AUTHORS file 1 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 # for details. All rights reserved. Use of this source code is governed by a 2 # for details. All rights reserved. Use of this source code is governed by a
3 # BSD-style license that can be found in the LICENSE file. 3 # BSD-style license that can be found in the LICENSE file.
4 4
5 # This file contains a set of utilities functions used by other Python-based 5 # This file contains a set of utilities functions used by other Python-based
6 # scripts. 6 # scripts.
7 7
8 import commands 8 import commands
9 import contextlib 9 import contextlib
10 import datetime 10 import datetime
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 os.chdir(self._old_cwd) 693 os.chdir(self._old_cwd)
694 694
695 695
696 class UnexpectedCrash(object): 696 class UnexpectedCrash(object):
697 def __init__(self, test, pid, binary): 697 def __init__(self, test, pid, binary):
698 self.test = test 698 self.test = test
699 self.pid = pid 699 self.pid = pid
700 self.binary = binary 700 self.binary = binary
701 701
702 def __str__(self): 702 def __str__(self):
703 return "%s: %s %s" % (self.test, self.binary, self.pid) 703 return "Crash(%s: %s %s)" % (self.test, self.binary, self.pid)
704 704
705 class SiteConfigBotoFileDisabler(object): 705 class SiteConfigBotoFileDisabler(object):
706 def __init__(self): 706 def __init__(self):
707 self._old_aws = None 707 self._old_aws = None
708 self._old_boto = None 708 self._old_boto = None
709 709
710 def __enter__(self): 710 def __enter__(self):
711 self._old_aws = os.environ.get('AWS_CREDENTIAL_FILE', None) 711 self._old_aws = os.environ.get('AWS_CREDENTIAL_FILE', None)
712 self._old_boto = os.environ.get('BOTO_CONFIG', None) 712 self._old_boto = os.environ.get('BOTO_CONFIG', None)
713 713
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
824 824
825 class BaseCoreDumpArchiver(object): 825 class BaseCoreDumpArchiver(object):
826 """This class reads coredumps file written by UnexpectedCrashDumpArchiver 826 """This class reads coredumps file written by UnexpectedCrashDumpArchiver
827 into the current working directory and uploads all cores and binaries 827 into the current working directory and uploads all cores and binaries
828 listed in it into Cloud Storage (see tools/testing/dart/test_progress.dart). 828 listed in it into Cloud Storage (see tools/testing/dart/test_progress.dart).
829 """ 829 """
830 830
831 # test.dart will write a line for each unexpected crash into this file. 831 # test.dart will write a line for each unexpected crash into this file.
832 _UNEXPECTED_CRASHES_FILE = "unexpected-crashes" 832 _UNEXPECTED_CRASHES_FILE = "unexpected-crashes"
833 833
834 def __init__(self): 834 def __init__(self, search_dir):
835 self._bucket = 'dart-temp-crash-archive' 835 self._bucket = 'dart-temp-crash-archive'
836 self._binaries_dir = os.getcwd() 836 self._binaries_dir = os.getcwd()
837 self._search_dir = search_dir
837 838
838 def __enter__(self): 839 def __enter__(self):
839 # Cleanup any stale files 840 # Cleanup any stale files
840 if self._cleanup(): 841 if self._cleanup():
841 print "WARNING: Found and removed stale coredumps" 842 print "WARNING: Found and removed stale coredumps"
842 843
843 def __exit__(self, *_): 844 def __exit__(self, *_):
844 try: 845 try:
845 crashes = self._find_unexpected_crashes() 846 crashes = self._find_unexpected_crashes()
846 if crashes: 847 if crashes:
(...skipping 17 matching lines...) Expand all
864 files = set() 865 files = set()
865 missing = [] 866 missing = []
866 for crash in crashes: 867 for crash in crashes:
867 files.add(crash.binary) 868 files.add(crash.binary)
868 core = self._find_coredump_file(crash) 869 core = self._find_coredump_file(crash)
869 if core: 870 if core:
870 files.add(core) 871 files.add(core)
871 else: 872 else:
872 missing.append(crash) 873 missing.append(crash)
873 self._upload(files) 874 self._upload(files)
875
874 if missing: 876 if missing:
875 raise Exception('Missing crash dumps for: %s' % ', '.join( 877 self._report_missing_crashes(missing, throw=True)
876 [str(c) for c in missing])) 878
879 def _report_missing_crashes(self, missing, throw=True):
880 missing_as_string = ', '.join([str(c) for c in missing])
881 other_files = list(glob.glob(os.path.join(self._search_dir, '*')))
882 print >> sys.stderr, (
883 "Could not find crash dumps for '%s' in search directory '%s'.\n"
884 "Existing files which *did not* match the pattern inside the search "
885 "directory are are:\n %s"
886 % (missing_as_string, self._search_dir, '\n '.join(other_files)))
887 if throw:
888 raise Exception('Missing crash dumps for: %s' % missing_as_string)
877 889
878 def _upload(self, files): 890 def _upload(self, files):
879 bot_utils = GetBotUtils() 891 bot_utils = GetBotUtils()
880 gsutil = bot_utils.GSUtil() 892 gsutil = bot_utils.GSUtil()
881 storage_path = '%s/%s/' % (self._bucket, uuid.uuid4()) 893 storage_path = '%s/%s/' % (self._bucket, uuid.uuid4())
882 gs_prefix = 'gs://%s' % storage_path 894 gs_prefix = 'gs://%s' % storage_path
883 http_prefix = 'https://storage.cloud.google.com/%s' % storage_path 895 http_prefix = 'https://storage.cloud.google.com/%s' % storage_path
884 896
885 print '\n--- Uploading into %s (%s) ---' % (gs_prefix, http_prefix) 897 print '\n--- Uploading into %s (%s) ---' % (gs_prefix, http_prefix)
886 for file in files: 898 for file in files:
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
927 if os.path.exists(BaseCoreDumpArchiver._UNEXPECTED_CRASHES_FILE): 939 if os.path.exists(BaseCoreDumpArchiver._UNEXPECTED_CRASHES_FILE):
928 os.unlink(BaseCoreDumpArchiver._UNEXPECTED_CRASHES_FILE) 940 os.unlink(BaseCoreDumpArchiver._UNEXPECTED_CRASHES_FILE)
929 found = True 941 found = True
930 for binary in glob.glob(os.path.join(self._binaries_dir, 'binary.*')): 942 for binary in glob.glob(os.path.join(self._binaries_dir, 'binary.*')):
931 found = True 943 found = True
932 os.unlink(binary) 944 os.unlink(binary)
933 return found 945 return found
934 946
935 class LinuxCoreDumpArchiver(BaseCoreDumpArchiver): 947 class LinuxCoreDumpArchiver(BaseCoreDumpArchiver):
936 def __init__(self): 948 def __init__(self):
937 super(self.__class__, self).__init__() 949 super(self.__class__, self).__init__(os.getcwd())
938 self._search_dir = os.getcwd()
939 950
940 def _cleanup(self): 951 def _cleanup(self):
941 found = super(self.__class__, self)._cleanup() 952 found = super(self.__class__, self)._cleanup()
942 for core in glob.glob(os.path.join(self._search_dir, 'core.*')): 953 for core in glob.glob(os.path.join(self._search_dir, 'core.*')):
943 found = True 954 found = True
944 os.unlink(core) 955 os.unlink(core)
945 return found 956 return found
946 957
947 def _find_coredump_file(self, crash): 958 def _find_coredump_file(self, crash):
948 core_filename = os.path.join(self._search_dir, 'core.%s' % crash.pid) 959 core_filename = os.path.join(self._search_dir, 'core.%s' % crash.pid)
949 if os.path.exists(core_filename): 960 if os.path.exists(core_filename):
950 return core_filename 961 return core_filename
951 962
952 class WindowsCoreDumpArchiver(BaseCoreDumpArchiver): 963 class WindowsCoreDumpArchiver(BaseCoreDumpArchiver):
953 def __init__(self): 964 def __init__(self):
954 super(self.__class__, self).__init__() 965 super(self.__class__, self).__init__(os.path.join(
955 self._search_dir = os.path.join( 966 os.getcwd(), WindowsCoredumpEnabler.WINDOWS_COREDUMP_FOLDER))
956 os.getcwd(), WindowsCoredumpEnabler.WINDOWS_COREDUMP_FOLDER)
957 967
958 def _cleanup(self): 968 def _cleanup(self):
959 found = super(self.__class__, self)._cleanup() 969 found = super(self.__class__, self)._cleanup()
960 for core in glob.glob(os.path.join(self._search_dir, '*')): 970 for core in glob.glob(os.path.join(self._search_dir, '*')):
961 found = True 971 found = True
962 os.unlink(core) 972 os.unlink(core)
963 return found 973 return found
964 974
965 def _find_coredump_file(self, crash): 975 def _find_coredump_file(self, crash):
966 pattern = os.path.join(self._search_dir, '*.%s.*' % crash.pid) 976 pattern = os.path.join(self._search_dir, '*.%s.*' % crash.pid)
967 for core_filename in glob.glob(pattern): 977 for core_filename in glob.glob(pattern):
968 return core_filename 978 return core_filename
969 979
980 def _report_missing_crashes(self, missing, throw=True):
981 # Let's only print the debugging information and not throw. We'll do more
982 # validation for werfault.exe and throw afterwards.
983 super(self.__class__, self)._report_missing_crashes(missing, throw=False)
984
985 # Let's check again for the image execution options for werfault. Maybe
986 # puppet came a long during testing and reverted our change.
987 try:
988 import winreg
989 except ImportError:
990 import _winreg as winreg
991 for wowbit in [winreg.KEY_WOW64_64KEY, winreg.KEY_WOW64_32KEY]:
992 try:
993 with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,
994 WindowsCoredumpEnabler.IMGEXEC_NAME,
995 0,
996 winreg.KEY_READ | wowbit) as handle:
997 raise Exception(
998 "Found werfault.exe was disabled. Probably by puppet. Too bad")
999 except OSError:
1000 # If the open did not work the werfault.exe execution setting is as it
1001 # should be.
1002 pass
1003
1004 if throw:
1005 missing_as_string = ', '.join([str(c) for c in missing])
1006 raise Exception('Missing crash dumps for: %s' % missing_as_string)
1007
970 @contextlib.contextmanager 1008 @contextlib.contextmanager
971 def NooptCoreDumpArchiver(): 1009 def NooptCoreDumpArchiver():
972 yield 1010 yield
973 1011
974 1012
975 def CoreDumpArchiver(args): 1013 def CoreDumpArchiver(args):
976 enabled = '--copy-coredumps' in args 1014 enabled = '--copy-coredumps' in args
977 1015
978 if not enabled: 1016 if not enabled:
979 return NooptCoreDumpArchiver() 1017 return NooptCoreDumpArchiver()
980 1018
981 osname = GuessOS() 1019 osname = GuessOS()
982 if osname == 'linux': 1020 if osname == 'linux':
983 return contextlib.nested(PosixCoredumpEnabler(), 1021 return contextlib.nested(PosixCoredumpEnabler(),
984 LinuxCoreDumpArchiver()) 1022 LinuxCoreDumpArchiver())
985 elif osname == 'win32': 1023 elif osname == 'win32':
986 return contextlib.nested(WindowsCoredumpEnabler(), 1024 return contextlib.nested(WindowsCoredumpEnabler(),
987 WindowsCoreDumpArchiver()) 1025 WindowsCoreDumpArchiver())
988 else: 1026 else:
989 # We don't have support for MacOS yet. 1027 # We don't have support for MacOS yet.
990 assert osname == 'macos' 1028 assert osname == 'macos'
991 return NooptCoreDumpArchiver() 1029 return NooptCoreDumpArchiver()
992 1030
993 if __name__ == "__main__": 1031 if __name__ == "__main__":
994 import sys 1032 import sys
995 Main() 1033 Main()
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698