summaryrefslogtreecommitdiffstats
path: root/third_party/tcmalloc
diff options
context:
space:
mode:
authordmikurube@chromium.org <dmikurube@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-06 19:29:51 +0000
committerdmikurube@chromium.org <dmikurube@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-06 19:29:51 +0000
commitac25573b5ef67e8e43d76f482d45cf1c70bf118f (patch)
treeb9a95b77cb45e8c159190faf8a7cc63439918456 /third_party/tcmalloc
parent79d7aef3813e887e72a0ce40156e0d00de1e7726 (diff)
downloadchromium_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.cc148
-rw-r--r--third_party/tcmalloc/chromium/src/deep-heap-profile.h15
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[]);