| OLD | NEW |
| 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 29 matching lines...) Expand all Loading... |
| 40 #include <errno.h> | 40 #include <errno.h> |
| 41 #ifdef HAVE_UNISTD_H | 41 #ifdef HAVE_UNISTD_H |
| 42 #include <unistd.h> | 42 #include <unistd.h> |
| 43 #endif | 43 #endif |
| 44 #ifdef HAVE_MMAP | 44 #ifdef HAVE_MMAP |
| 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 #ifdef HAVE_POLL_H |
| 51 #include <poll.h> |
| 52 #endif |
| 50 #include <sys/stat.h> | 53 #include <sys/stat.h> |
| 51 #include <sys/types.h> | 54 #include <sys/types.h> |
| 52 #include <time.h> | |
| 53 #include <assert.h> | 55 #include <assert.h> |
| 54 | 56 |
| 55 #ifdef HAVE_LINUX_PTRACE_H | 57 #ifdef HAVE_LINUX_PTRACE_H |
| 56 #include <linux/ptrace.h> | 58 #include <linux/ptrace.h> |
| 57 #endif | 59 #endif |
| 58 #ifdef HAVE_SYS_SYSCALL_H | 60 #ifdef HAVE_SYS_SYSCALL_H |
| 59 #include <sys/syscall.h> | 61 #include <sys/syscall.h> |
| 60 #endif | 62 #endif |
| 61 #if defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(_
_MINGW32__) | 63 #if defined(_WIN32) || defined(__CYGWIN__) || defined(__CYGWIN32__) || defined(_
_MINGW32__) |
| 62 #include <wtypes.h> | 64 #include <wtypes.h> |
| (...skipping 1762 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1825 // | 1827 // |
| 1826 // Because we crash when InternalInitStart is called more than once, | 1828 // Because we crash when InternalInitStart is called more than once, |
| 1827 // it's fine that we hold heap_checker_lock only around pieces of | 1829 // it's fine that we hold heap_checker_lock only around pieces of |
| 1828 // this function: this is still enough for thread-safety w.r.t. other functions | 1830 // this function: this is still enough for thread-safety w.r.t. other functions |
| 1829 // of this module. | 1831 // of this module. |
| 1830 // We can't hold heap_checker_lock throughout because it would deadlock | 1832 // We can't hold heap_checker_lock throughout because it would deadlock |
| 1831 // on a memory allocation since our new/delete hooks can be on. | 1833 // on a memory allocation since our new/delete hooks can be on. |
| 1832 // | 1834 // |
| 1833 /*static*/ void HeapLeakChecker::InternalInitStart() { | 1835 /*static*/ void HeapLeakChecker::InternalInitStart() { |
| 1834 { SpinLockHolder l(&heap_checker_lock); | 1836 { SpinLockHolder l(&heap_checker_lock); |
| 1835 RAW_CHECK(!internal_init_start_has_run, | 1837 RAW_CHECK(!internal_init_start_has_run, "Only one call is expected"); |
| 1836 "Heap-check constructor called twice. Perhaps you both linked" | |
| 1837 " in the heap checker, and also used LD_PRELOAD to load it?"); | |
| 1838 internal_init_start_has_run = true; | 1838 internal_init_start_has_run = true; |
| 1839 | 1839 |
| 1840 if (FLAGS_heap_check.empty()) { | 1840 if (FLAGS_heap_check.empty()) { |
| 1841 // turns out we do not need checking in the end; can stop profiling | 1841 // turns out we do not need checking in the end; can stop profiling |
| 1842 TurnItselfOffLocked(); | 1842 TurnItselfOffLocked(); |
| 1843 return; | 1843 return; |
| 1844 } | 1844 } |
| 1845 } | 1845 } |
| 1846 | 1846 |
| 1847 // Changing this to false can be useful when debugging heap-checker itself: | 1847 // Changing this to false can be useful when debugging heap-checker itself: |
| (...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2291 } | 2291 } |
| 2292 | 2292 |
| 2293 // This function is executed after all global object destructors run. | 2293 // This function is executed after all global object destructors run. |
| 2294 void HeapLeakChecker_AfterDestructors() { | 2294 void HeapLeakChecker_AfterDestructors() { |
| 2295 { SpinLockHolder l(&heap_checker_lock); | 2295 { SpinLockHolder l(&heap_checker_lock); |
| 2296 // can get here (via forks?) with other pids | 2296 // can get here (via forks?) with other pids |
| 2297 if (heap_checker_pid != getpid()) return; | 2297 if (heap_checker_pid != getpid()) return; |
| 2298 } | 2298 } |
| 2299 if (FLAGS_heap_check_after_destructors) { | 2299 if (FLAGS_heap_check_after_destructors) { |
| 2300 if (HeapLeakChecker::DoMainHeapCheck()) { | 2300 if (HeapLeakChecker::DoMainHeapCheck()) { |
| 2301 const struct timespec sleep_time = { 0, 500000000 }; // 500 ms | 2301 poll(0, 0, 500); |
| 2302 nanosleep(&sleep_time, NULL); | |
| 2303 // Need this hack to wait for other pthreads to exit. | 2302 // Need this hack to wait for other pthreads to exit. |
| 2304 // Otherwise tcmalloc find errors | 2303 // Otherwise tcmalloc find errors |
| 2305 // on a free() call from pthreads. | 2304 // on a free() call from pthreads. |
| 2306 } | 2305 } |
| 2307 } | 2306 } |
| 2308 SpinLockHolder l(&heap_checker_lock); | 2307 SpinLockHolder l(&heap_checker_lock); |
| 2309 RAW_CHECK(!do_main_heap_check, "should have done it"); | 2308 RAW_CHECK(!do_main_heap_check, "should have done it"); |
| 2310 } | 2309 } |
| 2311 | 2310 |
| 2312 //---------------------------------------------------------------------- | 2311 //---------------------------------------------------------------------- |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2362 // static | 2361 // static |
| 2363 const void* HeapLeakChecker::GetAllocCaller(void* ptr) { | 2362 const void* HeapLeakChecker::GetAllocCaller(void* ptr) { |
| 2364 // this is used only in the unittest, so the heavy checks are fine | 2363 // this is used only in the unittest, so the heavy checks are fine |
| 2365 HeapProfileTable::AllocInfo info; | 2364 HeapProfileTable::AllocInfo info; |
| 2366 { SpinLockHolder l(&heap_checker_lock); | 2365 { SpinLockHolder l(&heap_checker_lock); |
| 2367 RAW_CHECK(heap_profile->FindAllocDetails(ptr, &info), ""); | 2366 RAW_CHECK(heap_profile->FindAllocDetails(ptr, &info), ""); |
| 2368 } | 2367 } |
| 2369 RAW_CHECK(info.stack_depth >= 1, ""); | 2368 RAW_CHECK(info.stack_depth >= 1, ""); |
| 2370 return info.call_stack[0]; | 2369 return info.call_stack[0]; |
| 2371 } | 2370 } |
| OLD | NEW |