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

Side by Side Diff: base/process_util_mac.mm

Issue 11363208: [Mac] Remove potential for malloc in CrMallocErrorBreak(). (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: oops, can drop the include. Created 8 years, 1 month 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
« no previous file with comments | « no previous file | no next file » | 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) 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>
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after
583 private: 583 private:
584 ThreadLocalBoolean* scoped_tlb_; 584 ThreadLocalBoolean* scoped_tlb_;
585 bool original_value_; 585 bool original_value_;
586 586
587 DISALLOW_COPY_AND_ASSIGN(ThreadLocalBooleanAutoReset); 587 DISALLOW_COPY_AND_ASSIGN(ThreadLocalBooleanAutoReset);
588 }; 588 };
589 589
590 base::LazyInstance<ThreadLocalBoolean>::Leaky 590 base::LazyInstance<ThreadLocalBoolean>::Leaky
591 g_unchecked_malloc = LAZY_INSTANCE_INITIALIZER; 591 g_unchecked_malloc = LAZY_INSTANCE_INITIALIZER;
592 592
593 // NOTE(shess): This is called when the malloc library noticed that the heap
594 // is fubar. Avoid calls which will re-enter the malloc library.
593 void CrMallocErrorBreak() { 595 void CrMallocErrorBreak() {
594 g_original_malloc_error_break(); 596 g_original_malloc_error_break();
595 597
596 // Out of memory is certainly not heap corruption, and not necessarily 598 // Out of memory is certainly not heap corruption, and not necessarily
597 // something for which the process should be terminated. Leave that decision 599 // something for which the process should be terminated. Leave that decision
598 // to the OOM killer. The EBADF case comes up because the malloc library 600 // to the OOM killer. The EBADF case comes up because the malloc library
599 // attempts to log to ASL (syslog) before calling this code, which fails 601 // attempts to log to ASL (syslog) before calling this code, which fails
600 // accessing a Unix-domain socket because of sandboxing. 602 // accessing a Unix-domain socket because of sandboxing.
601 if (errno == ENOMEM || (errno == EBADF && g_unchecked_malloc.Get().Get())) 603 if (errno == ENOMEM || (errno == EBADF && g_unchecked_malloc.Get().Get()))
602 return; 604 return;
603 605
604 // A unit test checks this error message, so it needs to be in release builds. 606 // A unit test checks this error message, so it needs to be in release builds.
605 PLOG(ERROR) << 607 char buf[1024] =
606 "Terminating process due to a potential for future heap corruption"; 608 "Terminating process due to a potential for future heap corruption: "
609 "errno==";
Mark Mentovai 2012/11/12 23:19:32 One = too many?
Scott Hess - ex-Googler 2012/11/12 23:39:53 Done. I was thinking C-style is-equal-to, but a b
610 char errnobuf[4] = {
Mark Mentovai 2012/11/12 23:19:32 No [4], just [].
Scott Hess - ex-Googler 2012/11/12 23:39:53 Done.
611 '0' + ((errno / 100) % 10),
612 '0' + ((errno / 10) % 10),
613 '0' + (errno % 10),
614 '\000'
615 };
Mark Mentovai 2012/11/12 23:19:32 Ha! Do you want to COMPILE_ASSERT that ELAST <= 9
Scott Hess - ex-Googler 2012/11/12 23:39:53 Honestly, I kind of questioned even the third digi
616 strlcat(buf, errnobuf, sizeof(buf));
Mark Mentovai 2012/11/12 23:19:32 I can think of a way to avoid the copy, but that’s
Scott Hess - ex-Googler 2012/11/12 23:39:53 There are dozens of ways to skin this cat, and the
617 RAW_LOG(ERROR, buf);
607 618
608 // Crash by writing to NULL+errno to allow analyzing errno from 619 // Crash by writing to NULL+errno to allow analyzing errno from
609 // crash dump info (setting a breakpad key would re-enter the malloc 620 // crash dump info (setting a breakpad key would re-enter the malloc
610 // library). Max documented errno in intro(2) is actually 102, but 621 // library). Max documented errno in intro(2) is actually 102, but
611 // it really just needs to be "small" to stay on the right vm page. 622 // it really just needs to be "small" to stay on the right vm page.
612 const int kMaxErrno = 256; 623 const int kMaxErrno = 256;
613 char* volatile death_ptr = NULL; 624 char* volatile death_ptr = NULL;
614 death_ptr += std::min(errno, kMaxErrno); 625 death_ptr += std::min(errno, kMaxErrno);
615 *death_ptr = '!'; 626 *death_ptr = '!';
616 } 627 }
617 628
618 } // namespace 629 } // namespace
619 630
620 void EnableTerminationOnHeapCorruption() { 631 void EnableTerminationOnHeapCorruption() {
621 #ifdef ADDRESS_SANITIZER 632 #ifdef ADDRESS_SANITIZER
622 // Don't do anything special on heap corruption, because it should be handled 633 // Don't do anything special on heap corruption, because it should be handled
623 // by AddressSanitizer. 634 // by AddressSanitizer.
624 return; 635 return;
625 #endif 636 #endif
626 malloc_error_break_t malloc_error_break = LookUpMallocErrorBreak(); 637 malloc_error_break_t malloc_error_break = LookUpMallocErrorBreak();
627 if (!malloc_error_break) { 638 if (!malloc_error_break) {
628 DLOG(WARNING) << "Could not find malloc_error_break"; 639 DLOG(WARNING) << "Could not find malloc_error_break";
629 return; 640 return;
630 } 641 }
631 642
643 // Warm this up so that it doesn't require allocation when
644 // |CrMallocErrorBreak()| calls it.
645 ignore_result(g_unchecked_malloc.Get().Get());
646
632 mach_error_t err = mach_override_ptr( 647 mach_error_t err = mach_override_ptr(
633 (void*)malloc_error_break, 648 (void*)malloc_error_break,
634 (void*)&CrMallocErrorBreak, 649 (void*)&CrMallocErrorBreak,
635 (void**)&g_original_malloc_error_break); 650 (void**)&g_original_malloc_error_break);
636 651
637 if (err != err_none) 652 if (err != err_none)
638 DLOG(WARNING) << "Could not override malloc_error_break; error = " << err; 653 DLOG(WARNING) << "Could not override malloc_error_break; error = " << err;
639 } 654 }
640 655
641 // ------------------------------------------------------------------------ 656 // ------------------------------------------------------------------------
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after
1238 } 1253 }
1239 } 1254 }
1240 1255
1241 } // namespace 1256 } // namespace
1242 1257
1243 void EnsureProcessTerminated(ProcessHandle process) { 1258 void EnsureProcessTerminated(ProcessHandle process) {
1244 WaitForChildToDie(process, kWaitBeforeKillSeconds); 1259 WaitForChildToDie(process, kWaitBeforeKillSeconds);
1245 } 1260 }
1246 1261
1247 } // namespace base 1262 } // namespace base
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698