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

Side by Side Diff: base/process_util_mac.mm

Issue 7144007: Improve and unify Mac OS X run-time version checks (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « base/mac/mac_util_unittest.mm ('k') | base/sys_info.h » ('j') | 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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
6 #include "base/process_util.h" 5 #include "base/process_util.h"
7 6
8 #import <Cocoa/Cocoa.h> 7 #import <Cocoa/Cocoa.h>
9 #include <crt_externs.h> 8 #include <crt_externs.h>
10 #include <dlfcn.h> 9 #include <dlfcn.h>
11 #include <mach/mach.h> 10 #include <mach/mach.h>
12 #include <mach/mach_init.h> 11 #include <mach/mach_init.h>
13 #include <mach/mach_vm.h> 12 #include <mach/mach_vm.h>
14 #include <mach/shared_region.h> 13 #include <mach/shared_region.h>
15 #include <mach/task.h> 14 #include <mach/task.h>
16 #include <malloc/malloc.h> 15 #include <malloc/malloc.h>
17 #import <objc/runtime.h> 16 #import <objc/runtime.h>
18 #include <spawn.h> 17 #include <spawn.h>
19 #include <sys/mman.h> 18 #include <sys/mman.h>
20 #include <sys/sysctl.h> 19 #include <sys/sysctl.h>
21 #include <sys/types.h> 20 #include <sys/types.h>
22 #include <sys/utsname.h>
23 #include <sys/wait.h> 21 #include <sys/wait.h>
24 22
25 #include <new> 23 #include <new>
26 #include <string> 24 #include <string>
27 25
28 #include "base/debug/debugger.h" 26 #include "base/debug/debugger.h"
29 #include "base/eintr_wrapper.h" 27 #include "base/eintr_wrapper.h"
30 #include "base/hash_tables.h" 28 #include "base/hash_tables.h"
31 #include "base/logging.h" 29 #include "base/logging.h"
30 #include "base/mac/mac_util.h"
32 #include "base/string_util.h" 31 #include "base/string_util.h"
33 #include "base/sys_info.h" 32 #include "base/sys_info.h"
34 #include "base/sys_string_conversions.h" 33 #include "base/sys_string_conversions.h"
35 #include "base/time.h" 34 #include "base/time.h"
36 #include "third_party/apple_apsl/CFBase.h" 35 #include "third_party/apple_apsl/CFBase.h"
37 #include "third_party/apple_apsl/malloc.h" 36 #include "third_party/apple_apsl/malloc.h"
38 37
39 namespace base { 38 namespace base {
40 39
41 void RestoreDefaultExceptionHandler() { 40 void RestoreDefaultExceptionHandler() {
(...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 } 614 }
616 615
617 // === C++ operator new === 616 // === C++ operator new ===
618 617
619 void oom_killer_new() { 618 void oom_killer_new() {
620 debug::BreakDebugger(); 619 debug::BreakDebugger();
621 } 620 }
622 621
623 // === Core Foundation CFAllocators === 622 // === Core Foundation CFAllocators ===
624 623
625 bool CanGetContextForCFAllocator(long darwin_version) { 624 bool CanGetContextForCFAllocator() {
626 // TODO(avi): remove at final release; http://crbug.com/74589 625 // TODO(avi): remove at final release; http://crbug.com/74589
627 if (darwin_version == 11) { 626 if (base::mac::IsOSLion()) {
628 NSLog(@"Unsure about the internals of CFAllocator but going to patch them " 627 NSLog(@"Unsure about the internals of CFAllocator but going to patch them "
629 "anyway. Watch out for crashes inside of CFAllocatorAllocate."); 628 "anyway. Watch out for crashes inside of CFAllocatorAllocate.");
630 } 629 }
631 return darwin_version == 9 || 630 return !base::mac::IsOSLaterThanLion();
632 darwin_version == 10 ||
633 darwin_version == 11;
634 } 631 }
635 632
636 CFAllocatorContext* ContextForCFAllocator(CFAllocatorRef allocator, 633 CFAllocatorContext* ContextForCFAllocator(CFAllocatorRef allocator) {
637 long darwin_version) { 634 if (base::mac::IsOSLeopard() || base::mac::IsOSSnowLeopard()) {
638 if (darwin_version == 9 || darwin_version == 10) { 635 ChromeCFAllocatorLeopards* our_allocator =
639 ChromeCFAllocator9and10* our_allocator = 636 const_cast<ChromeCFAllocatorLeopards*>(
640 const_cast<ChromeCFAllocator9and10*>( 637 reinterpret_cast<const ChromeCFAllocatorLeopards*>(allocator));
641 reinterpret_cast<const ChromeCFAllocator9and10*>(allocator));
642 return &our_allocator->_context; 638 return &our_allocator->_context;
643 } else if (darwin_version == 11) { 639 } else if (base::mac::IsOSLion()) {
644 ChromeCFAllocator11* our_allocator = 640 ChromeCFAllocatorLion* our_allocator =
645 const_cast<ChromeCFAllocator11*>( 641 const_cast<ChromeCFAllocatorLion*>(
646 reinterpret_cast<const ChromeCFAllocator11*>(allocator)); 642 reinterpret_cast<const ChromeCFAllocatorLion*>(allocator));
647 return &our_allocator->_context; 643 return &our_allocator->_context;
648 } else { 644 } else {
649 return NULL; 645 return NULL;
650 } 646 }
651 } 647 }
652 648
653 CFAllocatorAllocateCallBack g_old_cfallocator_system_default; 649 CFAllocatorAllocateCallBack g_old_cfallocator_system_default;
654 CFAllocatorAllocateCallBack g_old_cfallocator_malloc; 650 CFAllocatorAllocateCallBack g_old_cfallocator_malloc;
655 CFAllocatorAllocateCallBack g_old_cfallocator_malloc_zone; 651 CFAllocatorAllocateCallBack g_old_cfallocator_malloc_zone;
656 652
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
707 return malloc_purgeable_zone(); 703 return malloc_purgeable_zone();
708 return NULL; 704 return NULL;
709 } 705 }
710 706
711 void EnableTerminationOnOutOfMemory() { 707 void EnableTerminationOnOutOfMemory() {
712 if (g_oom_killer_enabled) 708 if (g_oom_killer_enabled)
713 return; 709 return;
714 710
715 g_oom_killer_enabled = true; 711 g_oom_killer_enabled = true;
716 712
717 // Not SysInfo::OperatingSystemVersionNumbers as that calls through to Gestalt
718 // which ends up (on > 10.6) spawning threads.
719 struct utsname machine_info;
720 if (uname(&machine_info)) {
721 return;
722 }
723
724 // The string machine_info.release is the xnu/Darwin version number, "9.xxx"
725 // on Mac OS X 10.5, and "10.xxx" on Mac OS X 10.6. See
726 // http://en.wikipedia.org/wiki/Darwin_(operating_system) .
727 long darwin_version = strtol(machine_info.release, NULL, 10);
728
729 // === C malloc/calloc/valloc/realloc/posix_memalign === 713 // === C malloc/calloc/valloc/realloc/posix_memalign ===
730 714
731 // This approach is not perfect, as requests for amounts of memory larger than 715 // This approach is not perfect, as requests for amounts of memory larger than
732 // MALLOC_ABSOLUTE_MAX_SIZE (currently SIZE_T_MAX - (2 * PAGE_SIZE)) will 716 // MALLOC_ABSOLUTE_MAX_SIZE (currently SIZE_T_MAX - (2 * PAGE_SIZE)) will
733 // still fail with a NULL rather than dying (see 717 // still fail with a NULL rather than dying (see
734 // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c for details). 718 // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c for details).
735 // Unfortunately, it's the best we can do. Also note that this does not affect 719 // Unfortunately, it's the best we can do. Also note that this does not affect
736 // allocations from non-default zones. 720 // allocations from non-default zones.
737 721
738 CHECK(!g_old_malloc && !g_old_calloc && !g_old_valloc && !g_old_realloc && 722 CHECK(!g_old_malloc && !g_old_calloc && !g_old_valloc && !g_old_realloc &&
739 !g_old_memalign) << "Old allocators unexpectedly non-null"; 723 !g_old_memalign) << "Old allocators unexpectedly non-null";
740 724
741 CHECK(!g_old_malloc_purgeable && !g_old_calloc_purgeable && 725 CHECK(!g_old_malloc_purgeable && !g_old_calloc_purgeable &&
742 !g_old_valloc_purgeable && !g_old_realloc_purgeable && 726 !g_old_valloc_purgeable && !g_old_realloc_purgeable &&
743 !g_old_memalign_purgeable) << "Old allocators unexpectedly non-null"; 727 !g_old_memalign_purgeable) << "Old allocators unexpectedly non-null";
744 728
745 // See http://trac.webkit.org/changeset/53362/trunk/Tools/DumpRenderTree/mac 729 // See http://trac.webkit.org/changeset/53362/trunk/Tools/DumpRenderTree/mac
746 bool zone_allocators_protected = darwin_version > 10; 730 bool zone_allocators_protected = base::mac::IsOSLionOrLater();
747 731
748 ChromeMallocZone* default_zone = 732 ChromeMallocZone* default_zone =
749 reinterpret_cast<ChromeMallocZone*>(malloc_default_zone()); 733 reinterpret_cast<ChromeMallocZone*>(malloc_default_zone());
750 ChromeMallocZone* purgeable_zone = 734 ChromeMallocZone* purgeable_zone =
751 reinterpret_cast<ChromeMallocZone*>(GetPurgeableZone()); 735 reinterpret_cast<ChromeMallocZone*>(GetPurgeableZone());
752 736
753 vm_address_t page_start_default = NULL; 737 vm_address_t page_start_default = NULL;
754 vm_address_t page_start_purgeable = NULL; 738 vm_address_t page_start_purgeable = NULL;
755 vm_size_t len_default = 0; 739 vm_size_t len_default = 0;
756 vm_size_t len_purgeable = 0; 740 vm_size_t len_purgeable = 0;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
851 835
852 // === Core Foundation CFAllocators === 836 // === Core Foundation CFAllocators ===
853 837
854 // This will not catch allocation done by custom allocators, but will catch 838 // This will not catch allocation done by custom allocators, but will catch
855 // all allocation done by system-provided ones. 839 // all allocation done by system-provided ones.
856 840
857 CHECK(!g_old_cfallocator_system_default && !g_old_cfallocator_malloc && 841 CHECK(!g_old_cfallocator_system_default && !g_old_cfallocator_malloc &&
858 !g_old_cfallocator_malloc_zone) 842 !g_old_cfallocator_malloc_zone)
859 << "Old allocators unexpectedly non-null"; 843 << "Old allocators unexpectedly non-null";
860 844
861 bool cf_allocator_internals_known = 845 bool cf_allocator_internals_known = CanGetContextForCFAllocator();
862 CanGetContextForCFAllocator(darwin_version);
863 846
864 if (cf_allocator_internals_known) { 847 if (cf_allocator_internals_known) {
865 CFAllocatorContext* context = 848 CFAllocatorContext* context =
866 ContextForCFAllocator(kCFAllocatorSystemDefault, darwin_version); 849 ContextForCFAllocator(kCFAllocatorSystemDefault);
867 CHECK(context) << "Failed to get context for kCFAllocatorSystemDefault."; 850 CHECK(context) << "Failed to get context for kCFAllocatorSystemDefault.";
868 g_old_cfallocator_system_default = context->allocate; 851 g_old_cfallocator_system_default = context->allocate;
869 CHECK(g_old_cfallocator_system_default) 852 CHECK(g_old_cfallocator_system_default)
870 << "Failed to get kCFAllocatorSystemDefault allocation function."; 853 << "Failed to get kCFAllocatorSystemDefault allocation function.";
871 context->allocate = oom_killer_cfallocator_system_default; 854 context->allocate = oom_killer_cfallocator_system_default;
872 855
873 context = ContextForCFAllocator(kCFAllocatorMalloc, darwin_version); 856 context = ContextForCFAllocator(kCFAllocatorMalloc);
874 CHECK(context) << "Failed to get context for kCFAllocatorMalloc."; 857 CHECK(context) << "Failed to get context for kCFAllocatorMalloc.";
875 g_old_cfallocator_malloc = context->allocate; 858 g_old_cfallocator_malloc = context->allocate;
876 CHECK(g_old_cfallocator_malloc) 859 CHECK(g_old_cfallocator_malloc)
877 << "Failed to get kCFAllocatorMalloc allocation function."; 860 << "Failed to get kCFAllocatorMalloc allocation function.";
878 context->allocate = oom_killer_cfallocator_malloc; 861 context->allocate = oom_killer_cfallocator_malloc;
879 862
880 context = ContextForCFAllocator(kCFAllocatorMallocZone, darwin_version); 863 context = ContextForCFAllocator(kCFAllocatorMallocZone);
881 CHECK(context) << "Failed to get context for kCFAllocatorMallocZone."; 864 CHECK(context) << "Failed to get context for kCFAllocatorMallocZone.";
882 g_old_cfallocator_malloc_zone = context->allocate; 865 g_old_cfallocator_malloc_zone = context->allocate;
883 CHECK(g_old_cfallocator_malloc_zone) 866 CHECK(g_old_cfallocator_malloc_zone)
884 << "Failed to get kCFAllocatorMallocZone allocation function."; 867 << "Failed to get kCFAllocatorMallocZone allocation function.";
885 context->allocate = oom_killer_cfallocator_malloc_zone; 868 context->allocate = oom_killer_cfallocator_malloc_zone;
886 } else { 869 } else {
887 NSLog(@"Internals of CFAllocator not known; out-of-memory failures via " 870 NSLog(@"Internals of CFAllocator not known; out-of-memory failures via "
888 "CFAllocator will not result in termination. http://crbug.com/45650"); 871 "CFAllocator will not result in termination. http://crbug.com/45650");
889 } 872 }
890 873
(...skipping 23 matching lines...) Expand all
914 if (sysctl(mib, 4, &info, &length, NULL, 0) < 0) { 897 if (sysctl(mib, 4, &info, &length, NULL, 0) < 0) {
915 PLOG(ERROR) << "sysctl"; 898 PLOG(ERROR) << "sysctl";
916 return -1; 899 return -1;
917 } 900 }
918 if (length == 0) 901 if (length == 0)
919 return -1; 902 return -1;
920 return info.kp_eproc.e_ppid; 903 return info.kp_eproc.e_ppid;
921 } 904 }
922 905
923 } // namespace base 906 } // namespace base
OLDNEW
« no previous file with comments | « base/mac/mac_util_unittest.mm ('k') | base/sys_info.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698