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

Side by Side Diff: tools/utils.py

Issue 2815553003: Add support for core dump archiving on macos (Closed)
Patch Set: wrap in try-catch Created 3 years, 8 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 704 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 del os.environ['AWS_CREDENTIAL_FILE'] 715 del os.environ['AWS_CREDENTIAL_FILE']
716 if self._old_boto: 716 if self._old_boto:
717 del os.environ['BOTO_CONFIG'] 717 del os.environ['BOTO_CONFIG']
718 718
719 def __exit__(self, *_): 719 def __exit__(self, *_):
720 if self._old_aws: 720 if self._old_aws:
721 os.environ['AWS_CREDENTIAL_FILE'] = self._old_aws 721 os.environ['AWS_CREDENTIAL_FILE'] = self._old_aws
722 if self._old_boto: 722 if self._old_boto:
723 os.environ['BOTO_CONFIG'] = self._old_boto 723 os.environ['BOTO_CONFIG'] = self._old_boto
724 724
725 class PosixCoredumpEnabler(object): 725 class PosixCoreDumpEnabler(object):
726 def __init__(self): 726 def __init__(self):
727 self._old_limits = None 727 self._old_limits = None
728 728
729 def __enter__(self): 729 def __enter__(self):
730 self._old_limits = resource.getrlimit(resource.RLIMIT_CORE) 730 self._old_limits = resource.getrlimit(resource.RLIMIT_CORE)
731 731 resource.setrlimit(resource.RLIMIT_CORE, (-1, -1))
732 # Bump core limits to unlimited if core_pattern is correctly configured.
733 if CheckLinuxCoreDumpPattern(fatal=False):
734 resource.setrlimit(resource.RLIMIT_CORE, (-1, -1))
735 732
736 def __exit__(self, *_): 733 def __exit__(self, *_):
737 resource.setrlimit(resource.RLIMIT_CORE, self._old_limits) 734 resource.setrlimit(resource.RLIMIT_CORE, self._old_limits)
735
736 class LinuxCoreDumpEnabler(PosixCoreDumpEnabler):
737 def __enter__(self):
738 # Bump core limits to unlimited if core_pattern is correctly configured.
739 if CheckLinuxCoreDumpPattern(fatal=False):
740 super(LinuxCoreDumpEnabler, self).__enter__()
741
742 def __exit__(self, *args):
738 CheckLinuxCoreDumpPattern(fatal=True) 743 CheckLinuxCoreDumpPattern(fatal=True)
744 super(LinuxCoreDumpEnabler, self).__exit__(*args)
739 745
740 class WindowsCoredumpEnabler(object): 746 class WindowsCoreDumpEnabler(object):
741 """Configure Windows Error Reporting to store crash dumps. 747 """Configure Windows Error Reporting to store crash dumps.
742 748
743 The documentation can be found here: 749 The documentation can be found here:
744 https://msdn.microsoft.com/en-us/library/windows/desktop/bb787181.aspx 750 https://msdn.microsoft.com/en-us/library/windows/desktop/bb787181.aspx
745 """ 751 """
746 752
747 WINDOWS_COREDUMP_FOLDER = r'crashes' 753 WINDOWS_COREDUMP_FOLDER = r'crashes'
748 754
749 WER_NAME = r'SOFTWARE\Microsoft\Windows\Windows Error Reporting' 755 WER_NAME = r'SOFTWARE\Microsoft\Windows\Windows Error Reporting'
750 WER_LOCALDUMPS_NAME = r'%s\LocalDumps' % WER_NAME 756 WER_LOCALDUMPS_NAME = r'%s\LocalDumps' % WER_NAME
(...skipping 22 matching lines...) Expand all
773 self.winreg.KEY_ALL_ACCESS | sam) as wer: 779 self.winreg.KEY_ALL_ACCESS | sam) as wer:
774 with self.winreg.CreateKeyEx( 780 with self.winreg.CreateKeyEx(
775 self.winreg.HKEY_LOCAL_MACHINE, self.WER_LOCALDUMPS_NAME, 0, 781 self.winreg.HKEY_LOCAL_MACHINE, self.WER_LOCALDUMPS_NAME, 0,
776 self.winreg.KEY_ALL_ACCESS | sam) as wer_localdumps: 782 self.winreg.KEY_ALL_ACCESS | sam) as wer_localdumps:
777 # Prevent any modal UI dialog & disable normal windows error reporting 783 # Prevent any modal UI dialog & disable normal windows error reporting
778 # TODO(kustermann): Remove this once https://crbug.com/691971 is fixed 784 # TODO(kustermann): Remove this once https://crbug.com/691971 is fixed
779 self.winreg.SetValueEx(wer, "DontShowUI", 0, self.winreg.REG_DWORD, 1) 785 self.winreg.SetValueEx(wer, "DontShowUI", 0, self.winreg.REG_DWORD, 1)
780 self.winreg.SetValueEx(wer, "Disabled", 0, self.winreg.REG_DWORD, 1) 786 self.winreg.SetValueEx(wer, "Disabled", 0, self.winreg.REG_DWORD, 1)
781 787
782 coredump_folder = os.path.join( 788 coredump_folder = os.path.join(
783 os.getcwd(), WindowsCoredumpEnabler.WINDOWS_COREDUMP_FOLDER) 789 os.getcwd(), WindowsCoreDumpEnabler.WINDOWS_COREDUMP_FOLDER)
784 790
785 # Create the directory which will contain the dumps 791 # Create the directory which will contain the dumps
786 if not os.path.exists(coredump_folder): 792 if not os.path.exists(coredump_folder):
787 os.mkdir(coredump_folder) 793 os.mkdir(coredump_folder)
788 794
789 # Do full dumps (not just mini dumps), keep max 100 dumps and specify 795 # Do full dumps (not just mini dumps), keep max 100 dumps and specify
790 # folder. 796 # folder.
791 self.winreg.SetValueEx( 797 self.winreg.SetValueEx(
792 wer_localdumps, "DumpType", 0, self.winreg.REG_DWORD, 2) 798 wer_localdumps, "DumpType", 0, self.winreg.REG_DWORD, 2)
793 self.winreg.SetValueEx( 799 self.winreg.SetValueEx(
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
937 def _cleanup(self): 943 def _cleanup(self):
938 found = False 944 found = False
939 if os.path.exists(BaseCoreDumpArchiver._UNEXPECTED_CRASHES_FILE): 945 if os.path.exists(BaseCoreDumpArchiver._UNEXPECTED_CRASHES_FILE):
940 os.unlink(BaseCoreDumpArchiver._UNEXPECTED_CRASHES_FILE) 946 os.unlink(BaseCoreDumpArchiver._UNEXPECTED_CRASHES_FILE)
941 found = True 947 found = True
942 for binary in glob.glob(os.path.join(self._binaries_dir, 'binary.*')): 948 for binary in glob.glob(os.path.join(self._binaries_dir, 'binary.*')):
943 found = True 949 found = True
944 os.unlink(binary) 950 os.unlink(binary)
945 return found 951 return found
946 952
947 class LinuxCoreDumpArchiver(BaseCoreDumpArchiver): 953 class PosixCoreDumpArchiver(BaseCoreDumpArchiver):
948 def __init__(self): 954 def __init__(self, search_dir):
949 super(self.__class__, self).__init__(os.getcwd()) 955 super(PosixCoreDumpArchiver, self).__init__(search_dir)
950 956
951 def _cleanup(self): 957 def _cleanup(self):
952 found = super(self.__class__, self)._cleanup() 958 found = super(PosixCoreDumpArchiver, self)._cleanup()
953 for core in glob.glob(os.path.join(self._search_dir, 'core.*')): 959 for core in glob.glob(os.path.join(self._search_dir, 'core.*')):
954 found = True 960 found = True
955 os.unlink(core) 961 try:
962 os.unlink(core)
963 except:
964 pass
956 return found 965 return found
957 966
958 def _find_coredump_file(self, crash): 967 def _find_coredump_file(self, crash):
959 core_filename = os.path.join(self._search_dir, 'core.%s' % crash.pid) 968 core_filename = os.path.join(self._search_dir, 'core.%s' % crash.pid)
960 if os.path.exists(core_filename): 969 if os.path.exists(core_filename):
961 return core_filename 970 return core_filename
962 971
972 class LinuxCoreDumpArchiver(PosixCoreDumpArchiver):
973 def __init__(self):
974 super(LinuxCoreDumpArchiver, self).__init__(os.getcwd())
975
976 class MacOSCoreDumpArchiver(PosixCoreDumpArchiver):
977 def __init__(self):
978 super(MacOSCoreDumpArchiver, self).__init__('/cores')
979
963 class WindowsCoreDumpArchiver(BaseCoreDumpArchiver): 980 class WindowsCoreDumpArchiver(BaseCoreDumpArchiver):
964 def __init__(self): 981 def __init__(self):
965 super(self.__class__, self).__init__(os.path.join( 982 super(WindowsCoreDumpArchiver, self).__init__(os.path.join(
966 os.getcwd(), WindowsCoredumpEnabler.WINDOWS_COREDUMP_FOLDER)) 983 os.getcwd(), WindowsCoreDumpEnabler.WINDOWS_COREDUMP_FOLDER))
967 984
968 def _cleanup(self): 985 def _cleanup(self):
969 found = super(self.__class__, self)._cleanup() 986 found = super(WindowsCoreDumpArchiver, self)._cleanup()
970 for core in glob.glob(os.path.join(self._search_dir, '*')): 987 for core in glob.glob(os.path.join(self._search_dir, '*')):
971 found = True 988 found = True
972 os.unlink(core) 989 os.unlink(core)
973 return found 990 return found
974 991
975 def _find_coredump_file(self, crash): 992 def _find_coredump_file(self, crash):
976 pattern = os.path.join(self._search_dir, '*.%s.*' % crash.pid) 993 pattern = os.path.join(self._search_dir, '*.%s.*' % crash.pid)
977 for core_filename in glob.glob(pattern): 994 for core_filename in glob.glob(pattern):
978 return core_filename 995 return core_filename
979 996
980 def _report_missing_crashes(self, missing, throw=True): 997 def _report_missing_crashes(self, missing, throw=True):
981 # Let's only print the debugging information and not throw. We'll do more 998 # Let's only print the debugging information and not throw. We'll do more
982 # validation for werfault.exe and throw afterwards. 999 # validation for werfault.exe and throw afterwards.
983 super(self.__class__, self)._report_missing_crashes(missing, throw=False) 1000 super(WindowsCoreDumpArchiver, self)._report_missing_crashes(missing, throw= False)
984 1001
985 # Let's check again for the image execution options for werfault. Maybe 1002 # Let's check again for the image execution options for werfault. Maybe
986 # puppet came a long during testing and reverted our change. 1003 # puppet came a long during testing and reverted our change.
987 try: 1004 try:
988 import winreg 1005 import winreg
989 except ImportError: 1006 except ImportError:
990 import _winreg as winreg 1007 import _winreg as winreg
991 for wowbit in [winreg.KEY_WOW64_64KEY, winreg.KEY_WOW64_32KEY]: 1008 for wowbit in [winreg.KEY_WOW64_64KEY, winreg.KEY_WOW64_32KEY]:
992 try: 1009 try:
993 with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, 1010 with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,
994 WindowsCoredumpEnabler.IMGEXEC_NAME, 1011 WindowsCoreDumpEnabler.IMGEXEC_NAME,
995 0, 1012 0,
996 winreg.KEY_READ | wowbit) as handle: 1013 winreg.KEY_READ | wowbit) as handle:
997 raise Exception( 1014 raise Exception(
998 "Found werfault.exe was disabled. Probably by puppet. Too bad! " 1015 "Found werfault.exe was disabled. Probably by puppet. Too bad! "
999 "(For more information see https://crbug.com/691971)") 1016 "(For more information see https://crbug.com/691971)")
1000 except OSError: 1017 except OSError:
1001 # If the open did not work the werfault.exe execution setting is as it 1018 # If the open did not work the werfault.exe execution setting is as it
1002 # should be. 1019 # should be.
1003 pass 1020 pass
1004 1021
1005 if throw: 1022 if throw:
1006 missing_as_string = ', '.join([str(c) for c in missing]) 1023 missing_as_string = ', '.join([str(c) for c in missing])
1007 raise Exception('Missing crash dumps for: %s' % missing_as_string) 1024 raise Exception('Missing crash dumps for: %s' % missing_as_string)
1008 1025
1009 @contextlib.contextmanager 1026 @contextlib.contextmanager
1010 def NooptCoreDumpArchiver(): 1027 def NooptCoreDumpArchiver():
1011 yield 1028 yield
1012 1029
1013
1014 def CoreDumpArchiver(args): 1030 def CoreDumpArchiver(args):
1015 enabled = '--copy-coredumps' in args 1031 enabled = '--copy-coredumps' in args
1016 1032
1017 if not enabled: 1033 if not enabled:
1018 return NooptCoreDumpArchiver() 1034 return NooptCoreDumpArchiver()
1019 1035
1020 osname = GuessOS() 1036 osname = GuessOS()
1021 if osname == 'linux': 1037 if osname == 'linux':
1022 return contextlib.nested(PosixCoredumpEnabler(), 1038 return contextlib.nested(LinuxCoreDumpEnabler(),
1023 LinuxCoreDumpArchiver()) 1039 LinuxCoreDumpArchiver())
1040 elif osname == 'macos':
1041 return contextlib.nested(PosixCoreDumpEnabler(),
1042 MacOSCoreDumpArchiver())
1024 elif osname == 'win32': 1043 elif osname == 'win32':
1025 return contextlib.nested(WindowsCoredumpEnabler(), 1044 return contextlib.nested(WindowsCoreDumpEnabler(),
1026 WindowsCoreDumpArchiver()) 1045 WindowsCoreDumpArchiver())
1027 else: 1046 else:
1028 # We don't have support for MacOS yet. 1047 # We don't have support for MacOS yet.
1029 assert osname == 'macos' 1048 assert osname == 'macos'
1030 return NooptCoreDumpArchiver() 1049 return NooptCoreDumpArchiver()
1031 1050
1032 if __name__ == "__main__": 1051 if __name__ == "__main__":
1033 import sys 1052 import sys
1034 Main() 1053 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