OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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() |
OLD | NEW |