summaryrefslogtreecommitdiffstats
path: root/base/process_util_mac.mm
diff options
context:
space:
mode:
authoravi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-12 20:39:56 +0000
committeravi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-12 20:39:56 +0000
commitcccb2121a119f6d604878cf0524851bcdc9f3fff (patch)
tree0d03c64a48049728f713fc97123214f479142e3e /base/process_util_mac.mm
parentf06b43b8bf588d08631f5d3dc196fd9c0e9df3c7 (diff)
downloadchromium_src-cccb2121a119f6d604878cf0524851bcdc9f3fff.zip
chromium_src-cccb2121a119f6d604878cf0524851bcdc9f3fff.tar.gz
chromium_src-cccb2121a119f6d604878cf0524851bcdc9f3fff.tar.bz2
Ensure OOM is a killer on the Mac.
BUG=http://crbug.com/12673 TEST=as in bug Review URL: http://codereview.chromium.org/385054 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31819 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/process_util_mac.mm')
-rw-r--r--base/process_util_mac.mm90
1 files changed, 90 insertions, 0 deletions
diff --git a/base/process_util_mac.mm b/base/process_util_mac.mm
index e1574e5..ff6393e 100644
--- a/base/process_util_mac.mm
+++ b/base/process_util_mac.mm
@@ -10,6 +10,7 @@
#include <mach/mach.h>
#include <mach/mach_init.h>
#include <mach/task.h>
+#include <malloc/malloc.h>
#include <spawn.h>
#include <sys/sysctl.h>
#include <sys/types.h>
@@ -235,4 +236,93 @@ size_t GetSystemCommitCharge() {
return (data.active_count * page_size) / 1024;
}
+// ------------------------------------------------------------------------
+
+namespace {
+
+typedef void* (*malloc_type)(struct _malloc_zone_t* zone,
+ size_t size);
+typedef void* (*calloc_type)(struct _malloc_zone_t* zone,
+ size_t num_items,
+ size_t size);
+typedef void* (*valloc_type)(struct _malloc_zone_t* zone,
+ size_t size);
+typedef void* (*realloc_type)(struct _malloc_zone_t* zone,
+ void* ptr,
+ size_t size);
+
+malloc_type g_old_malloc;
+calloc_type g_old_calloc;
+valloc_type g_old_valloc;
+realloc_type g_old_realloc;
+
+void* oom_killer_malloc(struct _malloc_zone_t* zone,
+ size_t size) {
+ void* result = g_old_malloc(zone, size);
+ if (size)
+ CHECK(result) << "Out of memory, size = " << size;
+ return result;
+}
+
+void* oom_killer_calloc(struct _malloc_zone_t* zone,
+ size_t num_items,
+ size_t size) {
+ void* result = g_old_calloc(zone, num_items, size);
+ if (size)
+ CHECK(result) << "Out of memory, num_items = " << num_items
+ << ", size = " << size;
+ return result;
+}
+
+void* oom_killer_valloc(struct _malloc_zone_t* zone,
+ size_t size) {
+ void* result = g_old_valloc(zone, size);
+ if (size)
+ CHECK(result) << "Out of memory, size = " << size;
+ return result;
+}
+
+void* oom_killer_realloc(struct _malloc_zone_t* zone,
+ void* ptr,
+ size_t size) {
+ void* result = g_old_realloc(zone, ptr, size);
+ if (size)
+ CHECK(result) << "Out of memory, size = " << size;
+ return result;
+}
+
+} // namespace
+
+void EnableTerminationOnOutOfMemory() {
+ CHECK(!g_old_malloc && !g_old_calloc && !g_old_valloc && !g_old_realloc)
+ << "EnableTerminationOnOutOfMemory() called twice!";
+
+ // This approach is sub-optimal:
+ // - Requests for amounts of memory larger than MALLOC_ABSOLUTE_MAX_SIZE
+ // (currently SIZE_T_MAX - (2 * PAGE_SIZE)) will still fail with a NULL
+ // rather than dying (see
+ // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c for
+ // details).
+ // - It is unclear whether allocations via the C++ operator new() are affected
+ // by this (although it is likely).
+ // - This does not affect allocations from non-default zones.
+ // - It is unclear whether allocations from CoreFoundation's
+ // kCFAllocatorDefault or +[NSObject alloc] are affected by this.
+ // Nevertheless this is better than nothing for now.
+ // TODO(avi):Do better. http://crbug.com/12673
+
+ malloc_zone_t* default_zone = malloc_default_zone();
+ g_old_malloc = default_zone->malloc;
+ g_old_calloc = default_zone->calloc;
+ g_old_valloc = default_zone->valloc;
+ g_old_realloc = default_zone->realloc;
+ CHECK(g_old_malloc && g_old_calloc && g_old_valloc && g_old_realloc)
+ << "Failed to get system allocation functions.";
+
+ default_zone->malloc = oom_killer_malloc;
+ default_zone->calloc = oom_killer_calloc;
+ default_zone->valloc = oom_killer_valloc;
+ default_zone->realloc = oom_killer_realloc;
+}
+
} // namespace base