OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 #include <ctype.h> | 7 #include <ctype.h> |
8 #include <dirent.h> | 8 #include <dirent.h> |
| 9 #include <dlfcn.h> |
9 #include <errno.h> | 10 #include <errno.h> |
10 #include <fcntl.h> | 11 #include <fcntl.h> |
11 #include <sys/time.h> | 12 #include <sys/time.h> |
12 #include <sys/types.h> | 13 #include <sys/types.h> |
13 #include <sys/wait.h> | 14 #include <sys/wait.h> |
14 #include <time.h> | 15 #include <time.h> |
15 #include <unistd.h> | 16 #include <unistd.h> |
16 | 17 |
17 #include "base/file_util.h" | 18 #include "base/file_util.h" |
18 #include "base/logging.h" | 19 #include "base/logging.h" |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 | 491 |
491 size_t result_in_kb; | 492 size_t result_in_kb; |
492 result_in_kb = StringToInt(meminfo_fields[kMemTotalIndex]); | 493 result_in_kb = StringToInt(meminfo_fields[kMemTotalIndex]); |
493 result_in_kb -= StringToInt(meminfo_fields[kMemFreeIndex]); | 494 result_in_kb -= StringToInt(meminfo_fields[kMemFreeIndex]); |
494 result_in_kb -= StringToInt(meminfo_fields[kMemBuffersIndex]); | 495 result_in_kb -= StringToInt(meminfo_fields[kMemBuffersIndex]); |
495 result_in_kb -= StringToInt(meminfo_fields[kMemCacheIndex]); | 496 result_in_kb -= StringToInt(meminfo_fields[kMemCacheIndex]); |
496 | 497 |
497 return result_in_kb; | 498 return result_in_kb; |
498 } | 499 } |
499 | 500 |
| 501 namespace { |
| 502 |
| 503 void OnNoMemorySize(size_t size) { |
| 504 if (size != 0) |
| 505 CHECK(false) << "Out of memory, size = " << size; |
| 506 CHECK(false) << "Out of memory."; |
| 507 } |
| 508 |
| 509 void OnNoMemory() { |
| 510 OnNoMemorySize(0); |
| 511 } |
| 512 |
| 513 } // namespace |
| 514 |
| 515 extern "C" { |
| 516 |
| 517 #if defined(LINUX_USE_TCMALLOC) |
| 518 |
| 519 int tc_set_new_mode(int mode); |
| 520 |
| 521 #else // defined(LINUX_USE_TCMALLOC) |
| 522 |
| 523 typedef void* (*malloc_type)(size_t size); |
| 524 typedef void* (*valloc_type)(size_t size); |
| 525 typedef void* (*pvalloc_type)(size_t size); |
| 526 |
| 527 typedef void* (*calloc_type)(size_t nmemb, size_t size); |
| 528 typedef void* (*realloc_type)(void *ptr, size_t size); |
| 529 typedef void* (*memalign_type)(size_t boundary, size_t size); |
| 530 |
| 531 typedef int (*posix_memalign_type)(void **memptr, size_t alignment, |
| 532 size_t size); |
| 533 |
| 534 // Override the __libc_FOO name too. |
| 535 #define DIE_ON_OOM_1(function_name) \ |
| 536 _DIE_ON_OOM_1(function_name##_type, function_name) \ |
| 537 _DIE_ON_OOM_1(function_name##_type, __libc_##function_name) |
| 538 |
| 539 #define DIE_ON_OOM_2(function_name, arg1_type) \ |
| 540 _DIE_ON_OOM_2(function_name##_type, function_name, arg1_type) \ |
| 541 _DIE_ON_OOM_2(function_name##_type, __libc_##function_name, arg1_type) |
| 542 |
| 543 // posix_memalign doesn't have a __libc_ variant. |
| 544 #define DIE_ON_OOM_3INT(function_name) \ |
| 545 _DIE_ON_OOM_3INT(function_name##_type, function_name) |
| 546 |
| 547 #define _DIE_ON_OOM_1(function_type, function_name) \ |
| 548 void* function_name(size_t size) { \ |
| 549 static function_type original_function = \ |
| 550 reinterpret_cast<function_type>(dlsym(RTLD_NEXT, #function_name)); \ |
| 551 void* ret = original_function(size); \ |
| 552 if (ret == NULL && size != 0) \ |
| 553 OnNoMemorySize(size); \ |
| 554 return ret; \ |
| 555 } |
| 556 |
| 557 #define _DIE_ON_OOM_2(function_type, function_name, arg1_type) \ |
| 558 void* function_name(arg1_type arg1, size_t size) { \ |
| 559 static function_type original_function = \ |
| 560 reinterpret_cast<function_type>(dlsym(RTLD_NEXT, #function_name)); \ |
| 561 void* ret = original_function(arg1, size); \ |
| 562 if (ret == NULL && size != 0) \ |
| 563 OnNoMemorySize(size); \ |
| 564 return ret; \ |
| 565 } |
| 566 |
| 567 #define _DIE_ON_OOM_3INT(function_type, function_name) \ |
| 568 int function_name(void** ptr, size_t alignment, size_t size) { \ |
| 569 static function_type original_function = \ |
| 570 reinterpret_cast<function_type>(dlsym(RTLD_NEXT, #function_name)); \ |
| 571 int ret = original_function(ptr, alignment, size); \ |
| 572 if (ret == ENOMEM) \ |
| 573 OnNoMemorySize(size); \ |
| 574 return ret; \ |
| 575 } |
| 576 |
| 577 DIE_ON_OOM_1(malloc) |
| 578 DIE_ON_OOM_1(valloc) |
| 579 DIE_ON_OOM_1(pvalloc) |
| 580 |
| 581 DIE_ON_OOM_2(calloc, size_t) |
| 582 DIE_ON_OOM_2(realloc, void*) |
| 583 DIE_ON_OOM_2(memalign, size_t) |
| 584 |
| 585 DIE_ON_OOM_3INT(posix_memalign) |
| 586 |
| 587 #endif // defined(LINUX_USE_TCMALLOC) |
| 588 |
| 589 } // extern C |
| 590 |
500 void EnableTerminationOnOutOfMemory() { | 591 void EnableTerminationOnOutOfMemory() { |
501 // http://crbug.com/27222 | 592 // Set the new-out of memory handler. |
| 593 std::set_new_handler(&OnNoMemory); |
| 594 // If we're using glibc's allocator, the above functions will override |
| 595 // malloc and friends and make them die on out of memory. |
| 596 #if defined(LINUX_USE_TCMALLOC) |
| 597 // For tcmalloc, we just need to tell it to behave like new. |
| 598 tc_set_new_mode(1); |
| 599 #endif |
502 } | 600 } |
503 | 601 |
504 } // namespace base | 602 } // namespace base |
OLD | NEW |