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

Unified Diff: base/process_util_mac.mm

Issue 10908245: unchecked_malloc() for Skia on OSX. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Put EBADF/syslog commentary back. Created 8 years, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/process_util.h ('k') | base/process_util_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/process_util_mac.mm
diff --git a/base/process_util_mac.mm b/base/process_util_mac.mm
index b257021401726975aa33eb3fc7cc96b140964141..4885e4b18c6135ea08b1311eca24c1b0919ebd88 100644
--- a/base/process_util_mac.mm
+++ b/base/process_util_mac.mm
@@ -13,7 +13,6 @@
#include <mach/mach_vm.h>
#include <mach/shared_region.h>
#include <mach/task.h>
-#include <mach-o/dyld.h>
#include <mach-o/nlist.h>
#include <malloc/malloc.h>
#import <objc/runtime.h>
@@ -32,12 +31,12 @@
#include "base/eintr_wrapper.h"
#include "base/file_util.h"
#include "base/hash_tables.h"
+#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/mac/mac_util.h"
#include "base/string_util.h"
#include "base/sys_info.h"
-#include "base/sys_string_conversions.h"
-#include "base/time.h"
+#include "base/threading/thread_local.h"
#include "third_party/apple_apsl/CFBase.h"
#include "third_party/apple_apsl/malloc.h"
#include "third_party/mach_override/mach_override.h"
@@ -566,20 +565,53 @@ class ScopedClearErrno {
DISALLOW_COPY_AND_ASSIGN(ScopedClearErrno);
};
+// Combines ThreadLocalBoolean with AutoReset. It would be convenient
+// to compose ThreadLocalPointer<bool> with AutoReset<bool>, but that
+// would require allocating some storage for the bool.
+class ThreadLocalBooleanAutoReset {
+ public:
+ ThreadLocalBooleanAutoReset(ThreadLocalBoolean* tlb, bool new_value)
+ : scoped_tlb_(tlb),
+ original_value_(tlb->Get()) {
+ scoped_tlb_->Set(new_value);
+ }
+ ~ThreadLocalBooleanAutoReset() {
+ scoped_tlb_->Set(original_value_);
+ }
+
+ private:
+ ThreadLocalBoolean* scoped_tlb_;
+ bool original_value_;
+
+ DISALLOW_COPY_AND_ASSIGN(ThreadLocalBooleanAutoReset);
+};
+
+base::LazyInstance<ThreadLocalBoolean>::Leaky
+ g_unchecked_malloc = LAZY_INSTANCE_INITIALIZER;
+
void CrMallocErrorBreak() {
g_original_malloc_error_break();
// Out of memory is certainly not heap corruption, and not necessarily
// something for which the process should be terminated. Leave that decision
- // to the OOM killer.
- if (errno == ENOMEM)
+ // to the OOM killer. The EBADF case comes up because the malloc library
+ // attempts to log to ASL (syslog) before calling this code, which fails
+ // accessing a Unix-domain socket because of sandboxing.
+ if (errno == ENOMEM || (errno == EBADF && g_unchecked_malloc.Get().Get()))
return;
// A unit test checks this error message, so it needs to be in release builds.
- LOG(ERROR) <<
+ PLOG(ERROR) <<
"Terminating process due to a potential for future heap corruption";
- int* volatile death_ptr = NULL;
- *death_ptr = 0xf00bad;
+
+ // Crash by writing to NULL+errno to allow analyzing errno from
+ // crash dump info (setting a breakpad key would re-enter the malloc
+ // library). Max documented errno in intro(2) is actually 102, but
+ // it really just needs to be "small" to stay on the right vm page.
+ const int kMaxErrno = 256;
+ char* volatile death_ptr = NULL;
+ death_ptr += std::min(errno, kMaxErrno);
+ *death_ptr = '!';
}
} // namespace
@@ -836,16 +868,13 @@ id oom_killer_allocWithZone(id self, SEL _cmd, NSZone* zone)
} // namespace
-malloc_zone_t* GetPurgeableZone() {
- // malloc_default_purgeable_zone only exists on >= 10.6. Use dlsym to grab it
- // at runtime because it may not be present in the SDK used for compilation.
- typedef malloc_zone_t* (*malloc_default_purgeable_zone_t)(void);
- malloc_default_purgeable_zone_t malloc_purgeable_zone =
- reinterpret_cast<malloc_default_purgeable_zone_t>(
- dlsym(RTLD_DEFAULT, "malloc_default_purgeable_zone"));
- if (malloc_purgeable_zone)
- return malloc_purgeable_zone();
- return NULL;
+void* UncheckedMalloc(size_t size) {
+ if (g_old_malloc) {
+ ScopedClearErrno clear_errno;
+ ThreadLocalBooleanAutoReset flag(g_unchecked_malloc.Pointer(), true);
+ return g_old_malloc(malloc_default_zone(), size);
+ }
+ return malloc(size);
}
void EnableTerminationOnOutOfMemory() {
@@ -880,7 +909,7 @@ void EnableTerminationOnOutOfMemory() {
ChromeMallocZone* default_zone =
reinterpret_cast<ChromeMallocZone*>(malloc_default_zone());
ChromeMallocZone* purgeable_zone =
- reinterpret_cast<ChromeMallocZone*>(GetPurgeableZone());
+ reinterpret_cast<ChromeMallocZone*>(malloc_default_purgeable_zone());
vm_address_t page_start_default = 0;
vm_address_t page_start_purgeable = 0;
« no previous file with comments | « base/process_util.h ('k') | base/process_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698