OLD | NEW |
1 /* Copyright (c) 2006, Google Inc. | 1 /* Copyright (c) 2006, 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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 | 115 |
116 #include <algorithm> | 116 #include <algorithm> |
117 #include <set> | 117 #include <set> |
118 | 118 |
119 #include "memory_region_map.h" | 119 #include "memory_region_map.h" |
120 | 120 |
121 #include "base/logging.h" | 121 #include "base/logging.h" |
122 #include "base/low_level_alloc.h" | 122 #include "base/low_level_alloc.h" |
123 #include "malloc_hook-inl.h" | 123 #include "malloc_hook-inl.h" |
124 | 124 |
125 #include <gperftools/stacktrace.h> | 125 #include <google/stacktrace.h> |
126 #include <gperftools/malloc_hook.h> | 126 #include <google/malloc_hook.h> |
127 | 127 |
128 // MREMAP_FIXED is a linux extension. How it's used in this file, | 128 // MREMAP_FIXED is a linux extension. How it's used in this file, |
129 // setting it to 0 is equivalent to saying, "This feature isn't | 129 // setting it to 0 is equivalent to saying, "This feature isn't |
130 // supported", which is right. | 130 // supported", which is right. |
131 #ifndef MREMAP_FIXED | 131 #ifndef MREMAP_FIXED |
132 # define MREMAP_FIXED 0 | 132 # define MREMAP_FIXED 0 |
133 #endif | 133 #endif |
134 | 134 |
135 using std::max; | 135 using std::max; |
136 | 136 |
137 // ========================================================================= // | 137 // ========================================================================= // |
138 | 138 |
139 int MemoryRegionMap::client_count_ = 0; | 139 int MemoryRegionMap::client_count_ = 0; |
140 int MemoryRegionMap::max_stack_depth_ = 0; | 140 int MemoryRegionMap::max_stack_depth_ = 0; |
141 MemoryRegionMap::RegionSet* MemoryRegionMap::regions_ = NULL; | 141 MemoryRegionMap::RegionSet* MemoryRegionMap::regions_ = NULL; |
142 LowLevelAlloc::Arena* MemoryRegionMap::arena_ = NULL; | 142 LowLevelAlloc::Arena* MemoryRegionMap::arena_ = NULL; |
143 SpinLock MemoryRegionMap::lock_(SpinLock::LINKER_INITIALIZED); | 143 SpinLock MemoryRegionMap::lock_(SpinLock::LINKER_INITIALIZED); |
144 SpinLock MemoryRegionMap::owner_lock_( // ACQUIRED_AFTER(lock_) | 144 SpinLock MemoryRegionMap::owner_lock_( // ACQUIRED_AFTER(lock_) |
145 SpinLock::LINKER_INITIALIZED); | 145 SpinLock::LINKER_INITIALIZED); |
146 int MemoryRegionMap::recursion_count_ = 0; // GUARDED_BY(owner_lock_) | 146 int MemoryRegionMap::recursion_count_ = 0; // GUARDED_BY(owner_lock_) |
147 pthread_t MemoryRegionMap::lock_owner_tid_; // GUARDED_BY(owner_lock_) | 147 pthread_t MemoryRegionMap::lock_owner_tid_; // GUARDED_BY(owner_lock_) |
148 int64 MemoryRegionMap::map_size_ = 0; | |
149 int64 MemoryRegionMap::unmap_size_ = 0; | |
150 | 148 |
151 // ========================================================================= // | 149 // ========================================================================= // |
152 | 150 |
153 // Simple hook into execution of global object constructors, | 151 // Simple hook into execution of global object constructors, |
154 // so that we do not call pthread_self() when it does not yet work. | 152 // so that we do not call pthread_self() when it does not yet work. |
155 static bool libpthread_initialized = false; | 153 static bool libpthread_initialized = false; |
156 static bool initializer = (libpthread_initialized = true, true); | 154 static bool initializer = (libpthread_initialized = true, true); |
157 | 155 |
158 static inline bool current_thread_is(pthread_t should_be) { | 156 static inline bool current_thread_is(pthread_t should_be) { |
159 // Before main() runs, there's only one thread, so we're always that thread | 157 // Before main() runs, there's only one thread, so we're always that thread |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
457 ? MallocHook::GetCallerStackTrace(const_cast<void**>(region.call_stack), | 455 ? MallocHook::GetCallerStackTrace(const_cast<void**>(region.call_stack), |
458 max_stack_depth_, kStripFrames + 1) | 456 max_stack_depth_, kStripFrames + 1) |
459 : 0; | 457 : 0; |
460 region.set_call_stack_depth(depth); // record stack info fully | 458 region.set_call_stack_depth(depth); // record stack info fully |
461 RAW_VLOG(10, "New global region %p..%p from %p", | 459 RAW_VLOG(10, "New global region %p..%p from %p", |
462 reinterpret_cast<void*>(region.start_addr), | 460 reinterpret_cast<void*>(region.start_addr), |
463 reinterpret_cast<void*>(region.end_addr), | 461 reinterpret_cast<void*>(region.end_addr), |
464 reinterpret_cast<void*>(region.caller())); | 462 reinterpret_cast<void*>(region.caller())); |
465 // Note: none of the above allocates memory. | 463 // Note: none of the above allocates memory. |
466 Lock(); // recursively lock | 464 Lock(); // recursively lock |
467 map_size_ += size; | |
468 InsertRegionLocked(region); | 465 InsertRegionLocked(region); |
469 // This will (eventually) allocate storage for and copy over the stack data | 466 // This will (eventually) allocate storage for and copy over the stack data |
470 // from region.call_stack_data_ that is pointed by region.call_stack(). | 467 // from region.call_stack_data_ that is pointed by region.call_stack(). |
471 Unlock(); | 468 Unlock(); |
472 } | 469 } |
473 | 470 |
474 void MemoryRegionMap::RecordRegionRemoval(const void* start, size_t size) { | 471 void MemoryRegionMap::RecordRegionRemoval(const void* start, size_t size) { |
475 Lock(); | 472 Lock(); |
476 if (recursive_insert) { | 473 if (recursive_insert) { |
477 // First remove the removed region from saved_regions, if it's | 474 // First remove the removed region from saved_regions, if it's |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
569 InsertRegionLocked(r); | 566 InsertRegionLocked(r); |
570 continue; | 567 continue; |
571 } | 568 } |
572 ++region; | 569 ++region; |
573 } | 570 } |
574 RAW_VLOG(12, "Removed region %p..%p; have %"PRIuS" regions", | 571 RAW_VLOG(12, "Removed region %p..%p; have %"PRIuS" regions", |
575 reinterpret_cast<void*>(start_addr), | 572 reinterpret_cast<void*>(start_addr), |
576 reinterpret_cast<void*>(end_addr), | 573 reinterpret_cast<void*>(end_addr), |
577 regions_->size()); | 574 regions_->size()); |
578 if (VLOG_IS_ON(12)) LogAllLocked(); | 575 if (VLOG_IS_ON(12)) LogAllLocked(); |
579 unmap_size_ += size; | |
580 Unlock(); | 576 Unlock(); |
581 } | 577 } |
582 | 578 |
583 void MemoryRegionMap::MmapHook(const void* result, | 579 void MemoryRegionMap::MmapHook(const void* result, |
584 const void* start, size_t size, | 580 const void* start, size_t size, |
585 int prot, int flags, | 581 int prot, int flags, |
586 int fd, off_t offset) { | 582 int fd, off_t offset) { |
587 // TODO(maxim): replace all 0x%"PRIxS" by %p when RAW_VLOG uses a safe | 583 // TODO(maxim): replace all 0x%"PRIxS" by %p when RAW_VLOG uses a safe |
588 // snprintf reimplementation that does not malloc to pretty-print NULL | 584 // snprintf reimplementation that does not malloc to pretty-print NULL |
589 RAW_VLOG(10, "MMap = 0x%"PRIxPTR" of %"PRIuS" at %"PRIu64" " | 585 RAW_VLOG(10, "MMap = 0x%"PRIxPTR" of %"PRIuS" at %llu " |
590 "prot %d flags %d fd %d offs %"PRId64, | 586 "prot %d flags %d fd %d offs %lld", |
591 reinterpret_cast<uintptr_t>(result), size, | 587 reinterpret_cast<uintptr_t>(result), size, |
592 reinterpret_cast<uint64>(start), prot, flags, fd, | 588 reinterpret_cast<uint64>(start), prot, flags, fd, |
593 static_cast<int64>(offset)); | 589 static_cast<int64>(offset)); |
594 if (result != reinterpret_cast<void*>(MAP_FAILED) && size != 0) { | 590 if (result != reinterpret_cast<void*>(MAP_FAILED) && size != 0) { |
595 RecordRegionAddition(result, size); | 591 RecordRegionAddition(result, size); |
596 } | 592 } |
597 } | 593 } |
598 | 594 |
599 void MemoryRegionMap::MunmapHook(const void* ptr, size_t size) { | 595 void MemoryRegionMap::MunmapHook(const void* ptr, size_t size) { |
600 RAW_VLOG(10, "MUnmap of %p %"PRIuS"", ptr, size); | 596 RAW_VLOG(10, "MUnmap of %p %"PRIuS"", ptr, size); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
643 r != regions_->end(); ++r) { | 639 r != regions_->end(); ++r) { |
644 RAW_LOG(INFO, "Memory region 0x%"PRIxPTR"..0x%"PRIxPTR" " | 640 RAW_LOG(INFO, "Memory region 0x%"PRIxPTR"..0x%"PRIxPTR" " |
645 "from 0x%"PRIxPTR" stack=%d", | 641 "from 0x%"PRIxPTR" stack=%d", |
646 r->start_addr, r->end_addr, r->caller(), r->is_stack); | 642 r->start_addr, r->end_addr, r->caller(), r->is_stack); |
647 RAW_CHECK(previous < r->end_addr, "wow, we messed up the set order"); | 643 RAW_CHECK(previous < r->end_addr, "wow, we messed up the set order"); |
648 // this must be caused by uncontrolled recursive operations on regions_ | 644 // this must be caused by uncontrolled recursive operations on regions_ |
649 previous = r->end_addr; | 645 previous = r->end_addr; |
650 } | 646 } |
651 RAW_LOG(INFO, "End of regions list"); | 647 RAW_LOG(INFO, "End of regions list"); |
652 } | 648 } |
OLD | NEW |