| 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 <dlfcn.h> |
| 10 #include <errno.h> | 10 #include <errno.h> |
| (...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 typedef void* (*calloc_type)(size_t nmemb, size_t size); | 527 typedef void* (*calloc_type)(size_t nmemb, size_t size); |
| 528 typedef void* (*realloc_type)(void *ptr, size_t size); | 528 typedef void* (*realloc_type)(void *ptr, size_t size); |
| 529 typedef void* (*memalign_type)(size_t boundary, size_t size); | 529 typedef void* (*memalign_type)(size_t boundary, size_t size); |
| 530 | 530 |
| 531 typedef int (*posix_memalign_type)(void **memptr, size_t alignment, | 531 typedef int (*posix_memalign_type)(void **memptr, size_t alignment, |
| 532 size_t size); | 532 size_t size); |
| 533 | 533 |
| 534 // Override the __libc_FOO name too. | 534 // Override the __libc_FOO name too. |
| 535 #define DIE_ON_OOM_1(function_name) \ | 535 #define DIE_ON_OOM_1(function_name) \ |
| 536 _DIE_ON_OOM_1(function_name##_type, function_name) \ | 536 _DIE_ON_OOM_1(function_name##_type, function_name) \ |
| 537 _DIE_ON_OOM_1(function_name##_type, __libc_##function_name) | 537 void* __libc_##function_name(size_t size) { \ |
| 538 return function_name(size); \ |
| 539 } |
| 538 | 540 |
| 539 #define DIE_ON_OOM_2(function_name, arg1_type) \ | 541 #define DIE_ON_OOM_2(function_name, arg1_type) \ |
| 540 _DIE_ON_OOM_2(function_name##_type, function_name, arg1_type) \ | 542 _DIE_ON_OOM_2(function_name##_type, function_name, arg1_type) \ |
| 541 _DIE_ON_OOM_2(function_name##_type, __libc_##function_name, arg1_type) | 543 void* __libc_##function_name(arg1_type arg1, size_t size) { \ |
| 542 | 544 return function_name(arg1, size); \ |
| 543 // posix_memalign doesn't have a __libc_ variant. | 545 } |
| 544 #define DIE_ON_OOM_3INT(function_name) \ | |
| 545 _DIE_ON_OOM_3INT(function_name##_type, function_name) | |
| 546 | 546 |
| 547 #define _DIE_ON_OOM_1(function_type, function_name) \ | 547 #define _DIE_ON_OOM_1(function_type, function_name) \ |
| 548 void* function_name(size_t size) { \ | 548 void* function_name(size_t size) { \ |
| 549 static function_type original_function = \ | 549 static function_type original_function = \ |
| 550 reinterpret_cast<function_type>(dlsym(RTLD_NEXT, #function_name)); \ | 550 reinterpret_cast<function_type>(dlsym(RTLD_NEXT, #function_name)); \ |
| 551 void* ret = original_function(size); \ | 551 void* ret = original_function(size); \ |
| 552 if (ret == NULL && size != 0) \ | 552 if (ret == NULL && size != 0) \ |
| 553 OnNoMemorySize(size); \ | 553 OnNoMemorySize(size); \ |
| 554 return ret; \ | 554 return ret; \ |
| 555 } | 555 } |
| 556 | 556 |
| 557 #define _DIE_ON_OOM_2(function_type, function_name, arg1_type) \ | 557 #define _DIE_ON_OOM_2(function_type, function_name, arg1_type) \ |
| 558 void* function_name(arg1_type arg1, size_t size) { \ | 558 void* function_name(arg1_type arg1, size_t size) { \ |
| 559 static function_type original_function = \ | 559 static function_type original_function = \ |
| 560 reinterpret_cast<function_type>(dlsym(RTLD_NEXT, #function_name)); \ | 560 reinterpret_cast<function_type>(dlsym(RTLD_NEXT, #function_name)); \ |
| 561 void* ret = original_function(arg1, size); \ | 561 void* ret = original_function(arg1, size); \ |
| 562 if (ret == NULL && size != 0) \ | 562 if (ret == NULL && size != 0) \ |
| 563 OnNoMemorySize(size); \ | 563 OnNoMemorySize(size); \ |
| 564 return ret; \ | 564 return ret; \ |
| 565 } | 565 } |
| 566 | 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) | 567 DIE_ON_OOM_1(malloc) |
| 578 DIE_ON_OOM_1(valloc) | 568 DIE_ON_OOM_1(valloc) |
| 579 DIE_ON_OOM_1(pvalloc) | 569 DIE_ON_OOM_1(pvalloc) |
| 580 | 570 |
| 581 DIE_ON_OOM_2(calloc, size_t) | |
| 582 DIE_ON_OOM_2(realloc, void*) | 571 DIE_ON_OOM_2(realloc, void*) |
| 583 DIE_ON_OOM_2(memalign, size_t) | 572 DIE_ON_OOM_2(memalign, size_t) |
| 584 | 573 |
| 585 DIE_ON_OOM_3INT(posix_memalign) | 574 // dlsym uses calloc so it has to be treated specially. http://crbug.com/28244 |
| 575 static void* null_calloc(size_t nmemb, size_t size) { |
| 576 return NULL; |
| 577 } |
| 578 |
| 579 void* calloc(size_t nmemb, size_t size) { |
| 580 static calloc_type original_function = NULL; |
| 581 if (original_function == NULL) { |
| 582 original_function = null_calloc; |
| 583 original_function = reinterpret_cast<calloc_type>(dlsym(RTLD_NEXT, |
| 584 "calloc")); |
| 585 } |
| 586 void* ret = original_function(nmemb, size); |
| 587 if (ret == NULL && size != 0 && original_function != null_calloc) |
| 588 OnNoMemorySize(size); |
| 589 return ret; |
| 590 } |
| 591 |
| 592 void* __libc_calloc(size_t nmemb, size_t size) { \ |
| 593 return calloc(nmemb, size); |
| 594 } |
| 595 |
| 596 // posix_memalign has a unique signature and doesn't have a __libc_ variant. |
| 597 int posix_memalign(void** ptr, size_t alignment, size_t size) { |
| 598 static posix_memalign_type original_function = |
| 599 reinterpret_cast<posix_memalign_type>(dlsym(RTLD_NEXT, "posix_memalign")); |
| 600 int ret = original_function(ptr, alignment, size); |
| 601 if (ret == ENOMEM) |
| 602 OnNoMemorySize(size); |
| 603 return ret; |
| 604 } |
| 586 | 605 |
| 587 #endif // defined(LINUX_USE_TCMALLOC) | 606 #endif // defined(LINUX_USE_TCMALLOC) |
| 588 | 607 |
| 589 } // extern C | 608 } // extern C |
| 590 | 609 |
| 591 void EnableTerminationOnOutOfMemory() { | 610 void EnableTerminationOnOutOfMemory() { |
| 592 // Set the new-out of memory handler. | 611 // Set the new-out of memory handler. |
| 593 std::set_new_handler(&OnNoMemory); | 612 std::set_new_handler(&OnNoMemory); |
| 594 // If we're using glibc's allocator, the above functions will override | 613 // If we're using glibc's allocator, the above functions will override |
| 595 // malloc and friends and make them die on out of memory. | 614 // malloc and friends and make them die on out of memory. |
| 596 #if defined(LINUX_USE_TCMALLOC) | 615 #if defined(LINUX_USE_TCMALLOC) |
| 597 // For tcmalloc, we just need to tell it to behave like new. | 616 // For tcmalloc, we just need to tell it to behave like new. |
| 598 tc_set_new_mode(1); | 617 tc_set_new_mode(1); |
| 599 #endif | 618 #endif |
| 600 } | 619 } |
| 601 | 620 |
| 602 } // namespace base | 621 } // namespace base |
| OLD | NEW |