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

Side by Side Diff: third_party/tcmalloc/chromium/src/heap-checker.cc

Issue 7430007: Merge tcmalloc r111 (perftools v. 1.8) with the chromium/ branch. Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 4 months 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2005, Google Inc. 1 // Copyright (c) 2005, 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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 #include <sys/mman.h> 45 #include <sys/mman.h>
46 #endif 46 #endif
47 #ifdef HAVE_PTHREAD 47 #ifdef HAVE_PTHREAD
48 #include <pthread.h> 48 #include <pthread.h>
49 #endif 49 #endif
50 #include <sys/stat.h> 50 #include <sys/stat.h>
51 #include <sys/types.h> 51 #include <sys/types.h>
52 #include <time.h> 52 #include <time.h>
53 #include <assert.h> 53 #include <assert.h>
54 54
55 #ifdef HAVE_LINUX_PTRACE_H 55 #if defined(HAVE_LINUX_PTRACE_H) && !defined(__native_client__)
56 #include <linux/ptrace.h> 56 #include <linux/ptrace.h>
57 #endif 57 #endif
58 #ifdef HAVE_SYS_SYSCALL_H 58 #ifdef HAVE_SYS_SYSCALL_H
59 #include <sys/syscall.h> 59 #include <sys/syscall.h>
60 #endif 60 #endif
61 #if defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(_ _MINGW32__) 61 #if defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(_ _MINGW32__)
62 #include <wtypes.h> 62 #include <wtypes.h>
63 #include <winbase.h> 63 #include <winbase.h>
64 #undef ERROR // windows defines these as macros, which can cause trouble 64 #undef ERROR // windows defines these as macros, which can cause trouble
65 #undef max 65 #undef max
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 static pid_t heap_checker_pid = 0; 271 static pid_t heap_checker_pid = 0;
272 272
273 // If we did heap profiling during global constructors execution 273 // If we did heap profiling during global constructors execution
274 static bool constructor_heap_profiling = false; 274 static bool constructor_heap_profiling = false;
275 275
276 // RAW_VLOG level we dump key INFO messages at. If you want to turn 276 // RAW_VLOG level we dump key INFO messages at. If you want to turn
277 // off these messages, set the environment variable PERFTOOLS_VERBOSE=-1. 277 // off these messages, set the environment variable PERFTOOLS_VERBOSE=-1.
278 static const int heap_checker_info_level = 0; 278 static const int heap_checker_info_level = 0;
279 279
280 //---------------------------------------------------------------------- 280 //----------------------------------------------------------------------
281 // Cancel our InitialMallocHook_* if present.
282 static void CancelInitialMallocHooks(); // defined below
283
284 //----------------------------------------------------------------------
285 // HeapLeakChecker's own memory allocator that is 281 // HeapLeakChecker's own memory allocator that is
286 // independent of the normal program allocator. 282 // independent of the normal program allocator.
287 //---------------------------------------------------------------------- 283 //----------------------------------------------------------------------
288 284
289 // Wrapper of LowLevelAlloc for STL_Allocator and direct use. 285 // Wrapper of LowLevelAlloc for STL_Allocator and direct use.
290 // We always access this class under held heap_checker_lock, 286 // We always access this class under held heap_checker_lock,
291 // this allows us to in particular protect the period when threads are stopped 287 // this allows us to in particular protect the period when threads are stopped
292 // at random spots with ListAllProcessThreads by heap_checker_lock, 288 // at random spots with ListAllProcessThreads by heap_checker_lock,
293 // w/o worrying about the lock in LowLevelAlloc::Arena. 289 // w/o worrying about the lock in LowLevelAlloc::Arena.
294 // We rely on the fact that we use an own arena with an own lock here. 290 // We rely on the fact that we use an own arena with an own lock here.
(...skipping 917 matching lines...) Expand 10 before | Expand all | Expand 10 after
1212 // we can do everything in that main thread, 1208 // we can do everything in that main thread,
1213 // so that CPU profiler can collect all its samples. 1209 // so that CPU profiler can collect all its samples.
1214 // Returns the number of threads in the process. 1210 // Returns the number of threads in the process.
1215 static int IsOneThread(void* parameter, int num_threads, 1211 static int IsOneThread(void* parameter, int num_threads,
1216 pid_t* thread_pids, va_list ap) { 1212 pid_t* thread_pids, va_list ap) {
1217 if (num_threads != 1) { 1213 if (num_threads != 1) {
1218 RAW_LOG(WARNING, "Have threads: Won't CPU-profile the bulk of leak " 1214 RAW_LOG(WARNING, "Have threads: Won't CPU-profile the bulk of leak "
1219 "checking work happening in IgnoreLiveThreadsLocked!"); 1215 "checking work happening in IgnoreLiveThreadsLocked!");
1220 } 1216 }
1221 ResumeAllProcessThreads(num_threads, thread_pids); 1217 ResumeAllProcessThreads(num_threads, thread_pids);
1218 RAW_LOG(INFO, "IsOneThread returning %d", num_threads);
1222 return num_threads; 1219 return num_threads;
1223 } 1220 }
1224 1221
1225 // Dummy for IgnoreAllLiveObjectsLocked below. 1222 // Dummy for IgnoreAllLiveObjectsLocked below.
1226 // Making it global helps with compiler warnings. 1223 // Making it global helps with compiler warnings.
1227 static va_list dummy_ap; 1224 static va_list dummy_ap;
1228 1225
1229 // static 1226 // static
1230 void HeapLeakChecker::IgnoreAllLiveObjectsLocked(const void* self_stack_top) { 1227 void HeapLeakChecker::IgnoreAllLiveObjectsLocked(const void* self_stack_top) {
1231 RAW_DCHECK(heap_checker_lock.IsHeld(), ""); 1228 RAW_DCHECK(heap_checker_lock.IsHeld(), "");
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1269 bool want_and_can_run_in_main_thread = 1266 bool want_and_can_run_in_main_thread =
1270 ProfilingIsEnabledForAllThreads() && 1267 ProfilingIsEnabledForAllThreads() &&
1271 ListAllProcessThreads(NULL, IsOneThread) == 1; 1268 ListAllProcessThreads(NULL, IsOneThread) == 1;
1272 // When the normal path of ListAllProcessThreads below is taken, 1269 // When the normal path of ListAllProcessThreads below is taken,
1273 // we fully suspend the threads right here before any liveness checking 1270 // we fully suspend the threads right here before any liveness checking
1274 // and keep them suspended for the whole time of liveness checking 1271 // and keep them suspended for the whole time of liveness checking
1275 // inside of the IgnoreLiveThreadsLocked callback. 1272 // inside of the IgnoreLiveThreadsLocked callback.
1276 // (The threads can't (de)allocate due to lock on the delete hook but 1273 // (The threads can't (de)allocate due to lock on the delete hook but
1277 // if not suspended they could still mess with the pointer 1274 // if not suspended they could still mess with the pointer
1278 // graph while we walk it). 1275 // graph while we walk it).
1276 RAW_LOG(INFO, "want_and_can_run_in_main_thread: %d", want_and_can_run_in_mai n_thread);
1279 int r = want_and_can_run_in_main_thread 1277 int r = want_and_can_run_in_main_thread
1280 ? IgnoreLiveThreadsLocked(NULL, 1, &self_thread_pid, dummy_ap) 1278 ? IgnoreLiveThreadsLocked(NULL, 1, &self_thread_pid, dummy_ap)
1281 : ListAllProcessThreads(NULL, IgnoreLiveThreadsLocked); 1279 : ListAllProcessThreads(NULL, IgnoreLiveThreadsLocked);
1282 need_to_ignore_non_thread_objects = r < 0; 1280 need_to_ignore_non_thread_objects = r < 0;
1283 if (r < 0) { 1281 if (r < 0) {
1284 RAW_LOG(WARNING, "Thread finding failed with %d errno=%d", r, errno); 1282 RAW_LOG(WARNING, "Thread finding failed with %d errno=%d", r, errno);
1285 if (thread_listing_status == CALLBACK_COMPLETED) { 1283 if (thread_listing_status == CALLBACK_COMPLETED) {
1286 RAW_LOG(INFO, "Thread finding callback " 1284 RAW_LOG(INFO, "Thread finding callback "
1287 "finished ok; hopefully everything is fine"); 1285 "finished ok; hopefully everything is fine");
1288 need_to_ignore_non_thread_objects = false; 1286 need_to_ignore_non_thread_objects = false;
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
1466 if (!HaveOnHeapLocked(&ptr, &object_size)) { 1464 if (!HaveOnHeapLocked(&ptr, &object_size)) {
1467 RAW_LOG(ERROR, "No live heap object at %p to ignore", ptr); 1465 RAW_LOG(ERROR, "No live heap object at %p to ignore", ptr);
1468 } else { 1466 } else {
1469 RAW_VLOG(10, "Going to ignore live object at %p of %"PRIuS" bytes", 1467 RAW_VLOG(10, "Going to ignore live object at %p of %"PRIuS" bytes",
1470 ptr, object_size); 1468 ptr, object_size);
1471 if (ignored_objects == NULL) { 1469 if (ignored_objects == NULL) {
1472 ignored_objects = new(Allocator::Allocate(sizeof(IgnoredObjectsMap))) 1470 ignored_objects = new(Allocator::Allocate(sizeof(IgnoredObjectsMap)))
1473 IgnoredObjectsMap; 1471 IgnoredObjectsMap;
1474 } 1472 }
1475 if (!ignored_objects->insert(make_pair(AsInt(ptr), object_size)).second) { 1473 if (!ignored_objects->insert(make_pair(AsInt(ptr), object_size)).second) {
1476 RAW_LOG(FATAL, "Object at %p is already being ignored", ptr); 1474 RAW_LOG(WARNING, "Object at %p is already being ignored", ptr);
1477 } 1475 }
1478 } 1476 }
1479 } 1477 }
1480 1478
1481 // static 1479 // static
1482 void HeapLeakChecker::UnIgnoreObject(const void* ptr) { 1480 void HeapLeakChecker::UnIgnoreObject(const void* ptr) {
1483 SpinLockHolder l(&heap_checker_lock); 1481 SpinLockHolder l(&heap_checker_lock);
1484 if (!heap_checker_on) return; 1482 if (!heap_checker_on) return;
1485 size_t object_size; 1483 size_t object_size;
1486 if (!HaveOnHeapLocked(&ptr, &object_size)) { 1484 if (!HaveOnHeapLocked(&ptr, &object_size)) {
(...skipping 802 matching lines...) Expand 10 before | Expand all | Expand 10 after
2289 // static 2287 // static
2290 const void* HeapLeakChecker::GetAllocCaller(void* ptr) { 2288 const void* HeapLeakChecker::GetAllocCaller(void* ptr) {
2291 // this is used only in the unittest, so the heavy checks are fine 2289 // this is used only in the unittest, so the heavy checks are fine
2292 HeapProfileTable::AllocInfo info; 2290 HeapProfileTable::AllocInfo info;
2293 { SpinLockHolder l(&heap_checker_lock); 2291 { SpinLockHolder l(&heap_checker_lock);
2294 RAW_CHECK(heap_profile->FindAllocDetails(ptr, &info), ""); 2292 RAW_CHECK(heap_profile->FindAllocDetails(ptr, &info), "");
2295 } 2293 }
2296 RAW_CHECK(info.stack_depth >= 1, ""); 2294 RAW_CHECK(info.stack_depth >= 1, "");
2297 return info.call_stack[0]; 2295 return info.call_stack[0];
2298 } 2296 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698