OLD | NEW |
1 // Copyright (c) 2000, Google Inc. | 1 // Copyright (c) 2000, Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 public: // our main interface | 479 public: // our main interface |
480 | 480 |
481 static MallocBlock* Allocate(size_t size, int type) { | 481 static MallocBlock* Allocate(size_t size, int type) { |
482 // Prevent an integer overflow / crash with large allocation sizes. | 482 // Prevent an integer overflow / crash with large allocation sizes. |
483 // TODO - Note that for a e.g. 64-bit size_t, max_size_t may not actually | 483 // TODO - Note that for a e.g. 64-bit size_t, max_size_t may not actually |
484 // be the maximum value, depending on how the compiler treats ~0. The worst | 484 // be the maximum value, depending on how the compiler treats ~0. The worst |
485 // practical effect is that allocations are limited to 4Gb or so, even if | 485 // practical effect is that allocations are limited to 4Gb or so, even if |
486 // the address space could take more. | 486 // the address space could take more. |
487 static size_t max_size_t = ~0; | 487 static size_t max_size_t = ~0; |
488 if (size > max_size_t - sizeof(MallocBlock)) { | 488 if (size > max_size_t - sizeof(MallocBlock)) { |
489 RAW_LOG(ERROR, "Massive size passed to malloc: %"PRIuS"", size); | 489 RAW_LOG(ERROR, "Massive size passed to malloc: %" PRIuS "", size); |
490 return NULL; | 490 return NULL; |
491 } | 491 } |
492 MallocBlock* b = NULL; | 492 MallocBlock* b = NULL; |
493 const bool use_malloc_page_fence = FLAGS_malloc_page_fence; | 493 const bool use_malloc_page_fence = FLAGS_malloc_page_fence; |
494 #ifdef HAVE_MMAP | 494 #ifdef HAVE_MMAP |
495 if (use_malloc_page_fence) { | 495 if (use_malloc_page_fence) { |
496 // Put the block towards the end of the page and make the next page | 496 // Put the block towards the end of the page and make the next page |
497 // inaccessible. This will catch buffer overrun right when it happens. | 497 // inaccessible. This will catch buffer overrun right when it happens. |
498 size_t sz = real_mmapped_size(size); | 498 size_t sz = real_mmapped_size(size); |
499 int pagesize = getpagesize(); | 499 int pagesize = getpagesize(); |
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
958 } | 958 } |
959 } | 959 } |
960 | 960 |
961 // This protects MALLOC_TRACE, to make sure its info is atomically written. | 961 // This protects MALLOC_TRACE, to make sure its info is atomically written. |
962 static SpinLock malloc_trace_lock(SpinLock::LINKER_INITIALIZED); | 962 static SpinLock malloc_trace_lock(SpinLock::LINKER_INITIALIZED); |
963 | 963 |
964 #define MALLOC_TRACE(name, size, addr) \ | 964 #define MALLOC_TRACE(name, size, addr) \ |
965 do { \ | 965 do { \ |
966 if (FLAGS_malloctrace) { \ | 966 if (FLAGS_malloctrace) { \ |
967 SpinLockHolder l(&malloc_trace_lock); \ | 967 SpinLockHolder l(&malloc_trace_lock); \ |
968 TracePrintf(TraceFd(), "%s\t%"PRIuS"\t%p\t%"GPRIuPTHREAD, \ | 968 TracePrintf(TraceFd(), "%s\t%" PRIuS "\t%p\t%" GPRIuPTHREAD, \ |
969 name, size, addr, PRINTABLE_PTHREAD(pthread_self())); \ | 969 name, size, addr, PRINTABLE_PTHREAD(pthread_self())); \ |
970 TraceStack(); \ | 970 TraceStack(); \ |
971 TracePrintf(TraceFd(), "\n"); \ | 971 TracePrintf(TraceFd(), "\n"); \ |
972 } \ | 972 } \ |
973 } while (0) | 973 } while (0) |
974 | 974 |
975 // ========================================================================= // | 975 // ========================================================================= // |
976 | 976 |
977 // Write the characters buf[0, ..., size-1] to | 977 // Write the characters buf[0, ..., size-1] to |
978 // the malloc trace buffer. | 978 // the malloc trace buffer. |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1220 MallocHook::InvokeNewHook(p->data_addr(), size); | 1220 MallocHook::InvokeNewHook(p->data_addr(), size); |
1221 DebugDeallocate(ptr, MallocBlock::kMallocType); | 1221 DebugDeallocate(ptr, MallocBlock::kMallocType); |
1222 MALLOC_TRACE("realloc", p->data_size(), p->data_addr()); | 1222 MALLOC_TRACE("realloc", p->data_size(), p->data_addr()); |
1223 return p->data_addr(); | 1223 return p->data_addr(); |
1224 } | 1224 } |
1225 | 1225 |
1226 extern "C" PERFTOOLS_DLL_DECL void* tc_new(size_t size) { | 1226 extern "C" PERFTOOLS_DLL_DECL void* tc_new(size_t size) { |
1227 void* ptr = debug_cpp_alloc(size, MallocBlock::kNewType, false); | 1227 void* ptr = debug_cpp_alloc(size, MallocBlock::kNewType, false); |
1228 MallocHook::InvokeNewHook(ptr, size); | 1228 MallocHook::InvokeNewHook(ptr, size); |
1229 if (ptr == NULL) { | 1229 if (ptr == NULL) { |
1230 RAW_LOG(FATAL, "Unable to allocate %"PRIuS" bytes: new failed.", size); | 1230 RAW_LOG(FATAL, "Unable to allocate %" PRIuS " bytes: new failed.", size); |
1231 } | 1231 } |
1232 return ptr; | 1232 return ptr; |
1233 } | 1233 } |
1234 | 1234 |
1235 extern "C" PERFTOOLS_DLL_DECL void* tc_new_nothrow(size_t size, const std::nothr
ow_t&) __THROW { | 1235 extern "C" PERFTOOLS_DLL_DECL void* tc_new_nothrow(size_t size, const std::nothr
ow_t&) __THROW { |
1236 void* ptr = debug_cpp_alloc(size, MallocBlock::kNewType, true); | 1236 void* ptr = debug_cpp_alloc(size, MallocBlock::kNewType, true); |
1237 MallocHook::InvokeNewHook(ptr, size); | 1237 MallocHook::InvokeNewHook(ptr, size); |
1238 return ptr; | 1238 return ptr; |
1239 } | 1239 } |
1240 | 1240 |
1241 extern "C" PERFTOOLS_DLL_DECL void tc_delete(void* p) __THROW { | 1241 extern "C" PERFTOOLS_DLL_DECL void tc_delete(void* p) __THROW { |
1242 MallocHook::InvokeDeleteHook(p); | 1242 MallocHook::InvokeDeleteHook(p); |
1243 DebugDeallocate(p, MallocBlock::kNewType); | 1243 DebugDeallocate(p, MallocBlock::kNewType); |
1244 } | 1244 } |
1245 | 1245 |
1246 // Some STL implementations explicitly invoke this. | 1246 // Some STL implementations explicitly invoke this. |
1247 // It is completely equivalent to a normal delete (delete never throws). | 1247 // It is completely equivalent to a normal delete (delete never throws). |
1248 extern "C" PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p, const std::nothrow
_t&) __THROW { | 1248 extern "C" PERFTOOLS_DLL_DECL void tc_delete_nothrow(void* p, const std::nothrow
_t&) __THROW { |
1249 MallocHook::InvokeDeleteHook(p); | 1249 MallocHook::InvokeDeleteHook(p); |
1250 DebugDeallocate(p, MallocBlock::kNewType); | 1250 DebugDeallocate(p, MallocBlock::kNewType); |
1251 } | 1251 } |
1252 | 1252 |
1253 extern "C" PERFTOOLS_DLL_DECL void* tc_newarray(size_t size) { | 1253 extern "C" PERFTOOLS_DLL_DECL void* tc_newarray(size_t size) { |
1254 void* ptr = debug_cpp_alloc(size, MallocBlock::kArrayNewType, false); | 1254 void* ptr = debug_cpp_alloc(size, MallocBlock::kArrayNewType, false); |
1255 MallocHook::InvokeNewHook(ptr, size); | 1255 MallocHook::InvokeNewHook(ptr, size); |
1256 if (ptr == NULL) { | 1256 if (ptr == NULL) { |
1257 RAW_LOG(FATAL, "Unable to allocate %"PRIuS" bytes: new[] failed.", size); | 1257 RAW_LOG(FATAL, "Unable to allocate %" PRIuS " bytes: new[] failed.", size); |
1258 } | 1258 } |
1259 return ptr; | 1259 return ptr; |
1260 } | 1260 } |
1261 | 1261 |
1262 extern "C" PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size, const std::
nothrow_t&) | 1262 extern "C" PERFTOOLS_DLL_DECL void* tc_newarray_nothrow(size_t size, const std::
nothrow_t&) |
1263 __THROW { | 1263 __THROW { |
1264 void* ptr = debug_cpp_alloc(size, MallocBlock::kArrayNewType, true); | 1264 void* ptr = debug_cpp_alloc(size, MallocBlock::kArrayNewType, true); |
1265 MallocHook::InvokeNewHook(ptr, size); | 1265 MallocHook::InvokeNewHook(ptr, size); |
1266 return ptr; | 1266 return ptr; |
1267 } | 1267 } |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1431 return MallocExtension::instance()->GetAllocatedSize(ptr); | 1431 return MallocExtension::instance()->GetAllocatedSize(ptr); |
1432 } | 1432 } |
1433 | 1433 |
1434 #if defined(OS_LINUX) | 1434 #if defined(OS_LINUX) |
1435 extern "C" PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size) { | 1435 extern "C" PERFTOOLS_DLL_DECL void* tc_malloc_skip_new_handler(size_t size) { |
1436 void* result = DebugAllocate(size, MallocBlock::kMallocType); | 1436 void* result = DebugAllocate(size, MallocBlock::kMallocType); |
1437 MallocHook::InvokeNewHook(result, size); | 1437 MallocHook::InvokeNewHook(result, size); |
1438 return result; | 1438 return result; |
1439 } | 1439 } |
1440 #endif | 1440 #endif |
OLD | NEW |