| 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 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 954 void *pcs[16]; | 954 void *pcs[16]; |
| 955 int n = GetStackTrace(pcs, sizeof(pcs)/sizeof(pcs[0]), 0); | 955 int n = GetStackTrace(pcs, sizeof(pcs)/sizeof(pcs[0]), 0); |
| 956 for (int i = 0; i != n; i++) { | 956 for (int i = 0; i != n; i++) { |
| 957 TracePrintf(TraceFd(), "\t%p", pcs[i]); | 957 TracePrintf(TraceFd(), "\t%p", pcs[i]); |
| 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, name, size, \ |
| 969 name, size, addr, PRINTABLE_PTHREAD(pthread_self())); \ | 969 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. |
| 979 // This function is intended for debugging, | 979 // This function is intended for debugging, |
| 980 // and is not declared in any header file. | 980 // and is not declared in any header file. |
| 981 // You must insert a declaration of it by hand when you need | 981 // You must insert a declaration of it by hand when you need |
| 982 // to use it. | 982 // to use it. |
| (...skipping 237 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 |