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

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: tweaks from mark@. 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=";
610 char errnobuf[] = {
611 '0' + ((errno / 100) % 10),
612 '0' + ((errno / 10) % 10),
613 '0' + (errno % 10),
614 '\000'
615 };
616 COMPILE_ASSERT(ELAST <= 999, errno_too_large_to_encode);
617 strlcat(buf, errnobuf, sizeof(buf));
618 RAW_LOG(ERROR, buf);
607 619
608 // Crash by writing to NULL+errno to allow analyzing errno from 620 // Crash by writing to NULL+errno to allow analyzing errno from
609 // crash dump info (setting a breakpad key would re-enter the malloc 621 // crash dump info (setting a breakpad key would re-enter the malloc
610 // library). Max documented errno in intro(2) is actually 102, but 622 // 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. 623 // it really just needs to be "small" to stay on the right vm page.
612 const int kMaxErrno = 256; 624 const int kMaxErrno = 256;
613 char* volatile death_ptr = NULL; 625 char* volatile death_ptr = NULL;
614 death_ptr += std::min(errno, kMaxErrno); 626 death_ptr += std::min(errno, kMaxErrno);
615 *death_ptr = '!'; 627 *death_ptr = '!';
616 } 628 }
617 629
618 } // namespace 630 } // namespace
619 631
620 void EnableTerminationOnHeapCorruption() { 632 void EnableTerminationOnHeapCorruption() {
621 #ifdef ADDRESS_SANITIZER 633 #ifdef ADDRESS_SANITIZER
622 // Don't do anything special on heap corruption, because it should be handled 634 // Don't do anything special on heap corruption, because it should be handled
623 // by AddressSanitizer. 635 // by AddressSanitizer.
624 return; 636 return;
625 #endif 637 #endif
626 malloc_error_break_t malloc_error_break = LookUpMallocErrorBreak(); 638 malloc_error_break_t malloc_error_break = LookUpMallocErrorBreak();
627 if (!malloc_error_break) { 639 if (!malloc_error_break) {
628 DLOG(WARNING) << "Could not find malloc_error_break"; 640 DLOG(WARNING) << "Could not find malloc_error_break";
629 return; 641 return;
630 } 642 }
631 643
644 // Warm this up so that it doesn't require allocation when
645 // |CrMallocErrorBreak()| calls it.
646 ignore_result(g_unchecked_malloc.Get().Get());
647
632 mach_error_t err = mach_override_ptr( 648 mach_error_t err = mach_override_ptr(
633 (void*)malloc_error_break, 649 (void*)malloc_error_break,
634 (void*)&CrMallocErrorBreak, 650 (void*)&CrMallocErrorBreak,
635 (void**)&g_original_malloc_error_break); 651 (void**)&g_original_malloc_error_break);
636 652
637 if (err != err_none) 653 if (err != err_none)
638 DLOG(WARNING) << "Could not override malloc_error_break; error = " << err; 654 DLOG(WARNING) << "Could not override malloc_error_break; error = " << err;
639 } 655 }
640 656
641 // ------------------------------------------------------------------------ 657 // ------------------------------------------------------------------------
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after
1238 } 1254 }
1239 } 1255 }
1240 1256
1241 } // namespace 1257 } // namespace
1242 1258
1243 void EnsureProcessTerminated(ProcessHandle process) { 1259 void EnsureProcessTerminated(ProcessHandle process) {
1244 WaitForChildToDie(process, kWaitBeforeKillSeconds); 1260 WaitForChildToDie(process, kWaitBeforeKillSeconds);
1245 } 1261 }
1246 1262
1247 } // namespace base 1263 } // 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