| 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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 #include <sys/types.h> | 69 #include <sys/types.h> |
| 70 #include <stdlib.h> | 70 #include <stdlib.h> |
| 71 #include <errno.h> // errno | 71 #include <errno.h> // errno |
| 72 #ifdef HAVE_UNISTD_H | 72 #ifdef HAVE_UNISTD_H |
| 73 #include <unistd.h> // for sleep(), geteuid() | 73 #include <unistd.h> // for sleep(), geteuid() |
| 74 #endif | 74 #endif |
| 75 #ifdef HAVE_MMAP | 75 #ifdef HAVE_MMAP |
| 76 #include <sys/mman.h> | 76 #include <sys/mman.h> |
| 77 #endif | 77 #endif |
| 78 #include <fcntl.h> // for open(), close() | 78 #include <fcntl.h> // for open(), close() |
| 79 // FreeBSD has malloc.h, but complains if you use it | |
| 80 #if defined(HAVE_MALLOC_H) && !defined(__FreeBSD__) | |
| 81 #include <malloc.h> | |
| 82 #endif | |
| 83 | |
| 84 #ifdef HAVE_EXECINFO_H | 79 #ifdef HAVE_EXECINFO_H |
| 85 #include <execinfo.h> // backtrace | 80 #include <execinfo.h> // backtrace |
| 86 #endif | 81 #endif |
| 87 #ifdef HAVE_GRP_H | 82 #ifdef HAVE_GRP_H |
| 88 #include <grp.h> // getgrent, getgrnam | 83 #include <grp.h> // getgrent, getgrnam |
| 89 #endif | 84 #endif |
| 90 #ifdef HAVE_PWD_H | 85 #ifdef HAVE_PWD_H |
| 91 #include <pwd.h> | 86 #include <pwd.h> |
| 92 #endif | 87 #endif |
| 93 | 88 |
| 89 #include <algorithm> |
| 94 #include <iostream> // for cout | 90 #include <iostream> // for cout |
| 95 #include <iomanip> // for hex | 91 #include <iomanip> // for hex |
| 92 #include <list> |
| 93 #include <map> |
| 94 #include <memory> |
| 96 #include <set> | 95 #include <set> |
| 97 #include <map> | 96 #include <string> |
| 98 #include <list> | |
| 99 #include <memory> | |
| 100 #include <vector> | 97 #include <vector> |
| 101 #include <string> | |
| 102 | 98 |
| 99 #include "base/commandlineflags.h" |
| 103 #include "base/googleinit.h" | 100 #include "base/googleinit.h" |
| 104 #include "base/logging.h" | 101 #include "base/logging.h" |
| 105 #include "base/commandlineflags.h" | 102 #include "base/commandlineflags.h" |
| 106 #include "base/thread_lister.h" | 103 #include "base/thread_lister.h" |
| 107 #include <google/heap-checker.h> | 104 #include <google/heap-checker.h> |
| 108 #include "memory_region_map.h" | 105 #include "memory_region_map.h" |
| 109 #include <google/malloc_extension.h> | 106 #include <google/malloc_extension.h> |
| 110 #include <google/stacktrace.h> | 107 #include <google/stacktrace.h> |
| 111 | 108 |
| 112 // On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old | 109 // On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 } | 281 } |
| 285 | 282 |
| 286 // Make gcc think a pointer is "used" | 283 // Make gcc think a pointer is "used" |
| 287 template <class T> | 284 template <class T> |
| 288 static void Use(T** foo) { | 285 static void Use(T** foo) { |
| 289 VLOG(2) << "Dummy-using " << static_cast<void*>(*foo) << " at " << foo; | 286 VLOG(2) << "Dummy-using " << static_cast<void*>(*foo) << " at " << foo; |
| 290 } | 287 } |
| 291 | 288 |
| 292 // Arbitrary value, but not such that xor'ing with it is likely | 289 // Arbitrary value, but not such that xor'ing with it is likely |
| 293 // to map one valid pointer to another valid pointer: | 290 // to map one valid pointer to another valid pointer: |
| 294 static const uintptr_t kHideMask = 0xF03A5F7B; | 291 static const uintptr_t kHideMask = |
| 292 static_cast<uintptr_t>(0xF03A5F7BF03A5F7BLL); |
| 295 | 293 |
| 296 // Helpers to hide a pointer from live data traversal. | 294 // Helpers to hide a pointer from live data traversal. |
| 297 // We just xor the pointer so that (with high probability) | 295 // We just xor the pointer so that (with high probability) |
| 298 // it's not a valid address of a heap object anymore. | 296 // it's not a valid address of a heap object anymore. |
| 299 // Both Hide and UnHide must be executed within RunHidden() below | 297 // Both Hide and UnHide must be executed within RunHidden() below |
| 300 // to prevent leaving stale data on active stack that can be a pointer | 298 // to prevent leaving stale data on active stack that can be a pointer |
| 301 // to a heap object that is not actually reachable via live variables. | 299 // to a heap object that is not actually reachable via live variables. |
| 302 // (UnHide might leave heap pointer value for an object | 300 // (UnHide might leave heap pointer value for an object |
| 303 // that will be deallocated but later another object | 301 // that will be deallocated but later another object |
| 304 // can be allocated at the same heap address.) | 302 // can be allocated at the same heap address.) |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 676 // simple leak | 674 // simple leak |
| 677 static void TransLeaks() { | 675 static void TransLeaks() { |
| 678 AllocHidden(1 * sizeof(char)); | 676 AllocHidden(1 * sizeof(char)); |
| 679 } | 677 } |
| 680 | 678 |
| 681 // range-based disabling using Disabler | 679 // range-based disabling using Disabler |
| 682 static void ScopedDisabledLeaks() { | 680 static void ScopedDisabledLeaks() { |
| 683 HeapLeakChecker::Disabler disabler; | 681 HeapLeakChecker::Disabler disabler; |
| 684 AllocHidden(3 * sizeof(int)); | 682 AllocHidden(3 * sizeof(int)); |
| 685 TransLeaks(); | 683 TransLeaks(); |
| 686 malloc(10); // Direct leak | 684 (void)malloc(10); // Direct leak |
| 687 } | 685 } |
| 688 | 686 |
| 689 // have different disabled leaks | 687 // have different disabled leaks |
| 690 static void* RunDisabledLeaks(void* a) { | 688 static void* RunDisabledLeaks(void* a) { |
| 691 ScopedDisabledLeaks(); | 689 ScopedDisabledLeaks(); |
| 692 return a; | 690 return a; |
| 693 } | 691 } |
| 694 | 692 |
| 695 // have different disabled leaks inside of a thread | 693 // have different disabled leaks inside of a thread |
| 696 static void ThreadDisabledLeaks() { | 694 static void ThreadDisabledLeaks() { |
| (...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1484 CHECK(heap_check.SameHeap()); | 1482 CHECK(heap_check.SameHeap()); |
| 1485 } else { | 1483 } else { |
| 1486 WARN_IF(heap_check.SameHeap() != true, | 1484 WARN_IF(heap_check.SameHeap() != true, |
| 1487 "overall leaks are caught; we must be using a stripped binary"); | 1485 "overall leaks are caught; we must be using a stripped binary"); |
| 1488 } | 1486 } |
| 1489 | 1487 |
| 1490 CHECK(HeapLeakChecker::NoGlobalLeaks()); // so far, so good | 1488 CHECK(HeapLeakChecker::NoGlobalLeaks()); // so far, so good |
| 1491 | 1489 |
| 1492 return Pass(); | 1490 return Pass(); |
| 1493 } | 1491 } |
| OLD | NEW |