| 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 #include "base/process_util.h" | 5 #include "base/process_util.h" |
| 6 | 6 |
| 7 #import <Cocoa/Cocoa.h> | 7 #import <Cocoa/Cocoa.h> |
| 8 #include <crt_externs.h> | 8 #include <crt_externs.h> |
| 9 #include <dlfcn.h> | 9 #include <dlfcn.h> |
| 10 #include <errno.h> | 10 #include <errno.h> |
| 11 #include <mach/mach.h> | 11 #include <mach/mach.h> |
| 12 #include <mach/mach_init.h> | 12 #include <mach/mach_init.h> |
| 13 #include <mach/mach_vm.h> | 13 #include <mach/mach_vm.h> |
| 14 #include <mach/shared_region.h> | 14 #include <mach/shared_region.h> |
| 15 #include <mach/task.h> | 15 #include <mach/task.h> |
| 16 #include <mach-o/dyld.h> | |
| 17 #include <mach-o/nlist.h> | 16 #include <mach-o/nlist.h> |
| 18 #include <malloc/malloc.h> | 17 #include <malloc/malloc.h> |
| 19 #import <objc/runtime.h> | 18 #import <objc/runtime.h> |
| 20 #include <signal.h> | 19 #include <signal.h> |
| 21 #include <spawn.h> | 20 #include <spawn.h> |
| 22 #include <sys/event.h> | 21 #include <sys/event.h> |
| 23 #include <sys/mman.h> | 22 #include <sys/mman.h> |
| 24 #include <sys/sysctl.h> | 23 #include <sys/sysctl.h> |
| 25 #include <sys/types.h> | 24 #include <sys/types.h> |
| 26 #include <sys/wait.h> | 25 #include <sys/wait.h> |
| 27 | 26 |
| 28 #include <new> | 27 #include <new> |
| 29 #include <string> | 28 #include <string> |
| 30 | 29 |
| 31 #include "base/debug/debugger.h" | 30 #include "base/debug/debugger.h" |
| 32 #include "base/eintr_wrapper.h" | 31 #include "base/eintr_wrapper.h" |
| 33 #include "base/file_util.h" | 32 #include "base/file_util.h" |
| 34 #include "base/hash_tables.h" | 33 #include "base/hash_tables.h" |
| 35 #include "base/logging.h" | 34 #include "base/logging.h" |
| 36 #include "base/mac/mac_util.h" | 35 #include "base/mac/mac_util.h" |
| 37 #include "base/string_util.h" | 36 #include "base/string_util.h" |
| 38 #include "base/sys_info.h" | 37 #include "base/sys_info.h" |
| 39 #include "base/sys_string_conversions.h" | |
| 40 #include "base/time.h" | |
| 41 #include "third_party/apple_apsl/CFBase.h" | 38 #include "third_party/apple_apsl/CFBase.h" |
| 42 #include "third_party/apple_apsl/malloc.h" | 39 #include "third_party/apple_apsl/malloc.h" |
| 43 #include "third_party/mach_override/mach_override.h" | 40 #include "third_party/mach_override/mach_override.h" |
| 44 | 41 |
| 45 namespace base { | 42 namespace base { |
| 46 | 43 |
| 47 void RestoreDefaultExceptionHandler() { | 44 void RestoreDefaultExceptionHandler() { |
| 48 // This function is tailored to remove the Breakpad exception handler. | 45 // This function is tailored to remove the Breakpad exception handler. |
| 49 // exception_mask matches s_exception_mask in | 46 // exception_mask matches s_exception_mask in |
| 50 // breakpad/src/client/mac/handler/exception_handler.cc | 47 // breakpad/src/client/mac/handler/exception_handler.cc |
| (...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 void CrMallocErrorBreak() { | 566 void CrMallocErrorBreak() { |
| 570 g_original_malloc_error_break(); | 567 g_original_malloc_error_break(); |
| 571 | 568 |
| 572 // Out of memory is certainly not heap corruption, and not necessarily | 569 // Out of memory is certainly not heap corruption, and not necessarily |
| 573 // something for which the process should be terminated. Leave that decision | 570 // something for which the process should be terminated. Leave that decision |
| 574 // to the OOM killer. | 571 // to the OOM killer. |
| 575 if (errno == ENOMEM) | 572 if (errno == ENOMEM) |
| 576 return; | 573 return; |
| 577 | 574 |
| 578 // A unit test checks this error message, so it needs to be in release builds. | 575 // A unit test checks this error message, so it needs to be in release builds. |
| 579 LOG(ERROR) << | 576 PLOG(ERROR) << |
| 580 "Terminating process due to a potential for future heap corruption"; | 577 "Terminating process due to a potential for future heap corruption"; |
| 581 int* volatile death_ptr = NULL; | 578 int* volatile death_ptr = NULL; |
| 582 *death_ptr = 0xf00bad; | 579 *death_ptr = 0xf00bad; |
| 583 } | 580 } |
| 584 | 581 |
| 585 } // namespace | 582 } // namespace |
| 586 | 583 |
| 587 void EnableTerminationOnHeapCorruption() { | 584 void EnableTerminationOnHeapCorruption() { |
| 588 #ifdef ADDRESS_SANITIZER | 585 #ifdef ADDRESS_SANITIZER |
| 589 // Don't do anything special on heap corruption, because it should be handled | 586 // Don't do anything special on heap corruption, because it should be handled |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 829 id oom_killer_allocWithZone(id self, SEL _cmd, NSZone* zone) | 826 id oom_killer_allocWithZone(id self, SEL _cmd, NSZone* zone) |
| 830 { | 827 { |
| 831 id result = g_old_allocWithZone(self, _cmd, zone); | 828 id result = g_old_allocWithZone(self, _cmd, zone); |
| 832 if (!result) | 829 if (!result) |
| 833 debug::BreakDebugger(); | 830 debug::BreakDebugger(); |
| 834 return result; | 831 return result; |
| 835 } | 832 } |
| 836 | 833 |
| 837 } // namespace | 834 } // namespace |
| 838 | 835 |
| 839 malloc_zone_t* GetPurgeableZone() { | 836 void* UncheckedMalloc(size_t size) { |
| 840 // malloc_default_purgeable_zone only exists on >= 10.6. Use dlsym to grab it | 837 if (g_old_malloc) { |
| 841 // at runtime because it may not be present in the SDK used for compilation. | 838 ScopedClearErrno clear_errno; |
| 842 typedef malloc_zone_t* (*malloc_default_purgeable_zone_t)(void); | 839 return g_old_malloc(malloc_default_zone(), size); |
| 843 malloc_default_purgeable_zone_t malloc_purgeable_zone = | 840 } |
| 844 reinterpret_cast<malloc_default_purgeable_zone_t>( | 841 return malloc(size); |
| 845 dlsym(RTLD_DEFAULT, "malloc_default_purgeable_zone")); | |
| 846 if (malloc_purgeable_zone) | |
| 847 return malloc_purgeable_zone(); | |
| 848 return NULL; | |
| 849 } | 842 } |
| 850 | 843 |
| 851 void EnableTerminationOnOutOfMemory() { | 844 void EnableTerminationOnOutOfMemory() { |
| 852 if (g_oom_killer_enabled) | 845 if (g_oom_killer_enabled) |
| 853 return; | 846 return; |
| 854 | 847 |
| 855 g_oom_killer_enabled = true; | 848 g_oom_killer_enabled = true; |
| 856 | 849 |
| 857 // === C malloc/calloc/valloc/realloc/posix_memalign === | 850 // === C malloc/calloc/valloc/realloc/posix_memalign === |
| 858 | 851 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 873 #if !defined(ADDRESS_SANITIZER) | 866 #if !defined(ADDRESS_SANITIZER) |
| 874 // Don't do anything special on OOM for the malloc zones replaced by | 867 // Don't do anything special on OOM for the malloc zones replaced by |
| 875 // AddressSanitizer, as modifying or protecting them may not work correctly. | 868 // AddressSanitizer, as modifying or protecting them may not work correctly. |
| 876 | 869 |
| 877 // See http://trac.webkit.org/changeset/53362/trunk/Tools/DumpRenderTree/mac | 870 // See http://trac.webkit.org/changeset/53362/trunk/Tools/DumpRenderTree/mac |
| 878 bool zone_allocators_protected = base::mac::IsOSLionOrLater(); | 871 bool zone_allocators_protected = base::mac::IsOSLionOrLater(); |
| 879 | 872 |
| 880 ChromeMallocZone* default_zone = | 873 ChromeMallocZone* default_zone = |
| 881 reinterpret_cast<ChromeMallocZone*>(malloc_default_zone()); | 874 reinterpret_cast<ChromeMallocZone*>(malloc_default_zone()); |
| 882 ChromeMallocZone* purgeable_zone = | 875 ChromeMallocZone* purgeable_zone = |
| 883 reinterpret_cast<ChromeMallocZone*>(GetPurgeableZone()); | 876 reinterpret_cast<ChromeMallocZone*>(malloc_default_purgeable_zone()); |
| 884 | 877 |
| 885 vm_address_t page_start_default = 0; | 878 vm_address_t page_start_default = 0; |
| 886 vm_address_t page_start_purgeable = 0; | 879 vm_address_t page_start_purgeable = 0; |
| 887 vm_size_t len_default = 0; | 880 vm_size_t len_default = 0; |
| 888 vm_size_t len_purgeable = 0; | 881 vm_size_t len_purgeable = 0; |
| 889 if (zone_allocators_protected) { | 882 if (zone_allocators_protected) { |
| 890 page_start_default = reinterpret_cast<vm_address_t>(default_zone) & | 883 page_start_default = reinterpret_cast<vm_address_t>(default_zone) & |
| 891 static_cast<vm_size_t>(~(getpagesize() - 1)); | 884 static_cast<vm_size_t>(~(getpagesize() - 1)); |
| 892 len_default = reinterpret_cast<vm_address_t>(default_zone) - | 885 len_default = reinterpret_cast<vm_address_t>(default_zone) - |
| 893 page_start_default + sizeof(ChromeMallocZone); | 886 page_start_default + sizeof(ChromeMallocZone); |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1209 } | 1202 } |
| 1210 } | 1203 } |
| 1211 | 1204 |
| 1212 } // namespace | 1205 } // namespace |
| 1213 | 1206 |
| 1214 void EnsureProcessTerminated(ProcessHandle process) { | 1207 void EnsureProcessTerminated(ProcessHandle process) { |
| 1215 WaitForChildToDie(process, kWaitBeforeKillSeconds); | 1208 WaitForChildToDie(process, kWaitBeforeKillSeconds); |
| 1216 } | 1209 } |
| 1217 | 1210 |
| 1218 } // namespace base | 1211 } // namespace base |
| OLD | NEW |