diff options
author | dmikurube@chromium.org <dmikurube@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-06 19:29:51 +0000 |
---|---|---|
committer | dmikurube@chromium.org <dmikurube@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-06 19:29:51 +0000 |
commit | ac25573b5ef67e8e43d76f482d45cf1c70bf118f (patch) | |
tree | b9a95b77cb45e8c159190faf8a7cc63439918456 /third_party/tcmalloc | |
parent | 79d7aef3813e887e72a0ce40156e0d00de1e7726 (diff) | |
download | chromium_src-ac25573b5ef67e8e43d76f482d45cf1c70bf118f.zip chromium_src-ac25573b5ef67e8e43d76f482d45cf1c70bf118f.tar.gz chromium_src-ac25573b5ef67e8e43d76f482d45cf1c70bf118f.tar.bz2 |
Dump a list of memory regions which are hooked (mmap'ed) and not hooked by the heap-profiler.
It also stops to dump ".maps" files. The same information is contained in the list.
BUG=174304
Review URL: https://chromiumcodereview.appspot.com/12213037
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@181021 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party/tcmalloc')
-rw-r--r-- | third_party/tcmalloc/chromium/src/deep-heap-profile.cc | 148 | ||||
-rw-r--r-- | third_party/tcmalloc/chromium/src/deep-heap-profile.h | 15 |
2 files changed, 84 insertions, 79 deletions
diff --git a/third_party/tcmalloc/chromium/src/deep-heap-profile.cc b/third_party/tcmalloc/chromium/src/deep-heap-profile.cc index 895a527..3b56155 100644 --- a/third_party/tcmalloc/chromium/src/deep-heap-profile.cc +++ b/third_party/tcmalloc/chromium/src/deep-heap-profile.cc @@ -30,7 +30,8 @@ static const uint64 MAX_ADDRESS = kuint64max; // Tag strings in heap profile dumps. static const char kProfileHeader[] = "heap profile: "; -static const char kProfileVersion[] = "DUMP_DEEP_5"; +static const char kProfileVersion[] = "DUMP_DEEP_6"; +static const char kMMapListHeader[] = "MMAP_LIST:\n"; static const char kGlobalStatsHeader[] = "GLOBAL_STATS:\n"; static const char kStacktraceHeader[] = "STACKTRACES:\n"; static const char kProcSelfMapsHeader[] = "\nMAPPED_LIBRARIES:\n"; @@ -242,12 +243,8 @@ int DeepHeapProfile::FillOrderedProfile(char raw_buffer[], int buffer_size) { deep_table_.ResetIsLogged(); // Write maps into "|filename_prefix_|.<pid>.maps". - WriteProcMaps(filename_prefix_, 0, - kProfilerBufferSize, profiler_buffer_); + WriteProcMaps(filename_prefix_, kProfilerBufferSize, profiler_buffer_); } - // Write maps into "|filename_prefix_|.<pid>.|dump_count_|.maps". - WriteProcMaps(filename_prefix_, dump_count_, - kProfilerBufferSize, profiler_buffer_); // Reset committed sizes of buckets. deep_table_.ResetCommittedSize(); @@ -270,7 +267,7 @@ int DeepHeapProfile::FillOrderedProfile(char raw_buffer[], int buffer_size) { mmap_list_[num_mmap_allocations_ - 1].last_address = 0; } - stats_.SnapshotProcMaps(memory_residence_info_getter_, NULL, 0, NULL, 0); + stats_.SnapshotProcMaps(memory_residence_info_getter_, NULL, 0, NULL); // TODO(dmikurube): Eliminate dynamic memory allocation caused by snprintf. // glibc's snprintf internally allocates memory by alloca normally, but it @@ -279,16 +276,18 @@ int DeepHeapProfile::FillOrderedProfile(char raw_buffer[], int buffer_size) { // Record committed sizes. stats_.SnapshotAllocations(this); + buffer.AppendString(kProfileHeader, 0); + buffer.AppendString(kProfileVersion, 0); + buffer.AppendString("\n", 0); + + // Fill buffer with the global stats. + buffer.AppendString(kMMapListHeader, 0); + // Check if committed bytes changed during SnapshotAllocations. stats_.SnapshotProcMaps(memory_residence_info_getter_, mmap_list_, mmap_list_length_, - filename_prefix_, - dump_count_); - - buffer.AppendString(kProfileHeader, 0); - buffer.AppendString(kProfileVersion, 0); - buffer.AppendString("\n", 0); + &buffer); // Fill buffer with the global stats. buffer.AppendString(kGlobalStatsHeader, 0); @@ -606,13 +605,16 @@ void DeepHeapProfile::RegionStats::Initialize() { committed_bytes_ = 0; } -void DeepHeapProfile::RegionStats::Record( +uint64 DeepHeapProfile::RegionStats::Record( const MemoryResidenceInfoGetterInterface* memory_residence_info_getter, uint64 first_address, uint64 last_address) { + uint64 committed; virtual_bytes_ += static_cast<size_t>(last_address - first_address + 1); - committed_bytes_ += memory_residence_info_getter->CommittedSize(first_address, - last_address); + committed = memory_residence_info_getter->CommittedSize(first_address, + last_address); + committed_bytes_ += committed; + return committed; } void DeepHeapProfile::RegionStats::Unparse(const char* name, @@ -630,32 +632,31 @@ void DeepHeapProfile::GlobalStats::SnapshotProcMaps( const MemoryResidenceInfoGetterInterface* memory_residence_info_getter, MMapListEntry* mmap_list, int mmap_list_length, - const char* prefix, - int dump_count) { + TextBuffer* mmap_dump_buffer) { ProcMapsIterator::Buffer iterator_buffer; ProcMapsIterator iterator(0, &iterator_buffer); uint64 first_address, last_address, offset; - int64 unused_inode; + int64 inode; char* flags; char* filename; int mmap_list_index = 0; enum MapsRegionType type; - char unhooked_filename[100]; - RawFD unhooked_fd = kIllegalRawFD; for (int i = 0; i < NUMBER_OF_MAPS_REGION_TYPES; ++i) { all_[i].Initialize(); - nonprofiled_[i].Initialize(); - } - - if (prefix) { - snprintf(unhooked_filename, sizeof(unhooked_filename), - "%s.%05d.%04d.unhooked", prefix, getpid(), dump_count); - unhooked_fd = RawOpenForWriting(unhooked_filename); + unhooked_[i].Initialize(); } while (iterator.Next(&first_address, &last_address, - &flags, &offset, &unused_inode, &filename)) { + &flags, &offset, &inode, &filename)) { + if (mmap_dump_buffer) { + char buffer[1024]; + int written = iterator.FormatLine(buffer, sizeof(buffer), + first_address, last_address, flags, + offset, inode, filename, 0); + mmap_dump_buffer->AppendString(buffer, 0); + } + // 'last_address' should be the last inclusive address of the region. last_address -= 1; if (strcmp("[vsyscall]", filename) == 0) { @@ -679,7 +680,7 @@ void DeepHeapProfile::GlobalStats::SnapshotProcMaps( memory_residence_info_getter, first_address, last_address); // TODO(dmikurube): Stop double-counting pagemap. - // Counts nonprofiled memory regions in /proc/<pid>/maps. + // Counts unhooked memory regions in /proc/<pid>/maps. if (mmap_list != NULL) { // It assumes that every mmap'ed region is included in one maps line. uint64 cursor = first_address; @@ -693,40 +694,56 @@ void DeepHeapProfile::GlobalStats::SnapshotProcMaps( } first = false; - uint64 last_address_of_nonprofiled; + uint64 last_address_of_unhooked; // If the next mmap entry is away from the current maps line. if (mmap_list_index >= mmap_list_length || mmap_list[mmap_list_index].first_address > last_address) { - last_address_of_nonprofiled = last_address; + last_address_of_unhooked = last_address; } else { - last_address_of_nonprofiled = + last_address_of_unhooked = mmap_list[mmap_list_index].first_address - 1; + if (mmap_dump_buffer) { + bool trailing = + mmap_list[mmap_list_index].first_address < first_address; + bool continued = + mmap_list[mmap_list_index].last_address > last_address; + mmap_dump_buffer->AppendString(trailing ? " (" : " ", 0); + mmap_dump_buffer->AppendPtr( + mmap_list[mmap_list_index].first_address, 0); + mmap_dump_buffer->AppendString(trailing ? ")" : " ", 0); + mmap_dump_buffer->AppendString("-", 0); + mmap_dump_buffer->AppendString(continued ? "(" : " ", 0); + mmap_dump_buffer->AppendPtr( + mmap_list[mmap_list_index].last_address + 1, 0); + mmap_dump_buffer->AppendString(continued ? ")" : " ", 0); + mmap_dump_buffer->AppendString(" hooked ", 0); + mmap_dump_buffer->AppendString(kMapsRegionTypeDict[type], 0); + mmap_dump_buffer->AppendString("\n", 0); + } } - if (last_address_of_nonprofiled + 1 > cursor) { - nonprofiled_[type].Record( + if (last_address_of_unhooked + 1 > cursor) { + uint64 committed_size = unhooked_[type].Record( memory_residence_info_getter, cursor, - last_address_of_nonprofiled); - if (unhooked_fd != kIllegalRawFD) { - char range[128]; - int length = 0; - length = snprintf(range, sizeof(range), - "%s %"PRIxPTR"-%"PRIxPTR"\n", - kMapsRegionTypeDict[type], - cursor, last_address_of_nonprofiled); - if (length > 0) - RawWrite(unhooked_fd, range, length); + last_address_of_unhooked); + if (mmap_dump_buffer) { + mmap_dump_buffer->AppendString(" ", 0); + mmap_dump_buffer->AppendPtr(cursor, 0); + mmap_dump_buffer->AppendString(" - ", 0); + mmap_dump_buffer->AppendPtr(last_address_of_unhooked + 1, 0); + mmap_dump_buffer->AppendString(" unhooked ", 0); + mmap_dump_buffer->AppendString(kMapsRegionTypeDict[type], 0); + mmap_dump_buffer->AppendString(" ", 0); + mmap_dump_buffer->AppendInt64(committed_size, 0); + mmap_dump_buffer->AppendString("\n", 0); } - cursor = last_address_of_nonprofiled + 1; + cursor = last_address_of_unhooked + 1; } } while (mmap_list_index < mmap_list_length && mmap_list[mmap_list_index].last_address <= last_address); } } - - if (unhooked_fd != kIllegalRawFD) - RawClose(unhooked_fd); } void DeepHeapProfile::GlobalStats::SnapshotAllocations( @@ -750,10 +767,10 @@ void DeepHeapProfile::GlobalStats::SnapshotAllocations( void DeepHeapProfile::GlobalStats::Unparse(TextBuffer* buffer) { RegionStats all_total; - RegionStats nonprofiled_total; + RegionStats unhooked_total; for (int i = 0; i < NUMBER_OF_MAPS_REGION_TYPES; ++i) { all_total.AddAnotherRegionStat(all_[i]); - nonprofiled_total.AddAnotherRegionStat(nonprofiled_[i]); + unhooked_total.AddAnotherRegionStat(unhooked_[i]); } // "# total (%lu) %c= profiled-mmap (%lu) + nonprofiled-* (%lu)\n" @@ -762,11 +779,11 @@ void DeepHeapProfile::GlobalStats::Unparse(TextBuffer* buffer) { buffer->AppendString(") ", 0); buffer->AppendChar(all_total.committed_bytes() == profiled_mmap_.committed_bytes() + - nonprofiled_total.committed_bytes() ? '=' : '!'); + unhooked_total.committed_bytes() ? '=' : '!'); buffer->AppendString("= profiled-mmap (", 0); buffer->AppendUnsignedLong(profiled_mmap_.committed_bytes(), 0); buffer->AppendString(") + nonprofiled-* (", 0); - buffer->AppendUnsignedLong(nonprofiled_total.committed_bytes(), 0); + buffer->AppendUnsignedLong(unhooked_total.committed_bytes(), 0); buffer->AppendString(")\n", 0); // " virtual committed" @@ -782,13 +799,13 @@ void DeepHeapProfile::GlobalStats::Unparse(TextBuffer* buffer) { all_[ANONYMOUS].Unparse("anonymous", buffer); all_[STACK].Unparse("stack", buffer); all_[OTHER].Unparse("other", buffer); - nonprofiled_total.Unparse("nonprofiled-total", buffer); - nonprofiled_[ABSENT].Unparse("nonprofiled-absent", buffer); - nonprofiled_[ANONYMOUS].Unparse("nonprofiled-anonymous", buffer); - nonprofiled_[FILE_EXEC].Unparse("nonprofiled-file-exec", buffer); - nonprofiled_[FILE_NONEXEC].Unparse("nonprofiled-file-nonexec", buffer); - nonprofiled_[STACK].Unparse("nonprofiled-stack", buffer); - nonprofiled_[OTHER].Unparse("nonprofiled-other", buffer); + unhooked_total.Unparse("nonprofiled-total", buffer); + unhooked_[ABSENT].Unparse("nonprofiled-absent", buffer); + unhooked_[ANONYMOUS].Unparse("nonprofiled-anonymous", buffer); + unhooked_[FILE_EXEC].Unparse("nonprofiled-file-exec", buffer); + unhooked_[FILE_NONEXEC].Unparse("nonprofiled-file-nonexec", buffer); + unhooked_[STACK].Unparse("nonprofiled-stack", buffer); + unhooked_[OTHER].Unparse("nonprofiled-other", buffer); profiled_mmap_.Unparse("profiled-mmap", buffer); profiled_malloc_.Unparse("profiled-malloc", buffer); } @@ -852,18 +869,11 @@ void DeepHeapProfile::GlobalStats::RecordMMap(const void* pointer, // static void DeepHeapProfile::WriteProcMaps(const char* prefix, - unsigned count, int buffer_size, char raw_buffer[]) { char filename[100]; - if (count > 0) { - snprintf(filename, sizeof(filename), - "%s.%05d.%04d.maps", prefix, static_cast<int>(getpid()), - count); - } else { - snprintf(filename, sizeof(filename), - "%s.%05d.maps", prefix, static_cast<int>(getpid())); - } + snprintf(filename, sizeof(filename), + "%s.%05d.maps", prefix, static_cast<int>(getpid())); RawFD fd = RawOpenForWriting(filename); RAW_DCHECK(fd != kIllegalRawFD, ""); diff --git a/third_party/tcmalloc/chromium/src/deep-heap-profile.h b/third_party/tcmalloc/chromium/src/deep-heap-profile.h index 435a061..3f0ac89 100644 --- a/third_party/tcmalloc/chromium/src/deep-heap-profile.h +++ b/third_party/tcmalloc/chromium/src/deep-heap-profile.h @@ -228,7 +228,7 @@ class DeepHeapProfile { // Updates itself to contain the tallies of 'virtual_bytes' and // 'committed_bytes' in the region from |first_adress| to |last_address| // inclusive. - void Record( + uint64 Record( const MemoryResidenceInfoGetterInterface* memory_residence_info_getter, uint64 first_address, uint64 last_address); @@ -261,8 +261,7 @@ class DeepHeapProfile { const MemoryResidenceInfoGetterInterface* memory_residence_info_getter, MMapListEntry* mmap_list, int mmap_list_length, - const char* prefix, - int dump_count); + TextBuffer* mmap_dump_buffer); // Snapshots allocations by malloc and mmap. void SnapshotAllocations(DeepHeapProfile* deep_profile); @@ -289,7 +288,7 @@ class DeepHeapProfile { // for more detailed analysis. RegionStats all_[NUMBER_OF_MAPS_REGION_TYPES]; - RegionStats nonprofiled_[NUMBER_OF_MAPS_REGION_TYPES]; + RegionStats unhooked_[NUMBER_OF_MAPS_REGION_TYPES]; // Total bytes of malloc'ed regions. RegionStats profiled_malloc_; @@ -298,13 +297,9 @@ class DeepHeapProfile { RegionStats profiled_mmap_; }; - // Writes reformatted /proc/<pid>/maps into a file with using |raw_buffer| - // of |buffer_size|. - // - // If |count| is zero, the filename will be "|prefix|.<pid>.maps". - // Otherwise, "|prefix|.<pid>.|count|.maps". + // Writes reformatted /proc/<pid>/maps into a file "|prefix|.<pid>.maps" + // with using |raw_buffer| of |buffer_size|. static void WriteProcMaps(const char* prefix, - unsigned count, int buffer_size, char raw_buffer[]); |