summaryrefslogtreecommitdiff
path: root/src/malloc_extension.cc
diff options
context:
space:
mode:
authorcsilvers <csilvers@6b5cf1ce-ec42-a296-1ba9-69fdba395a50>2007-03-22 04:44:18 +0000
committercsilvers <csilvers@6b5cf1ce-ec42-a296-1ba9-69fdba395a50>2007-03-22 04:44:18 +0000
commitee5805f1296f8546c16f90d5427efa347a5f7338 (patch)
tree38870545181491e1e98bd7cd901d8d276d1bc223 /src/malloc_extension.cc
parentbc455d7b63949fab94ed9518d277866e95f08768 (diff)
downloadgperftools-ee5805f1296f8546c16f90d5427efa347a5f7338.tar.gz
Wed Oct 26 15:19:16 2005 Google Inc. <opensource@google.com>
* Decrease fragmentation in tcmalloc (lefevere) * Support for ARM in some of the thread-specific code (markus) * Turn off heap-checker for statically-linked binaries, which cause error leak reports now (etune) * Many pprof improvements, including a command-line interface (jeff) * CPU profiling now automatically affects all threads in linux 2.6. (Kernel bugs break CPU profiling and threads in linux 2.4 a bit.) ProfilerEnable() and ProfilerDisable() are deprecated. (sanjay) * tcmalloc now correctly intercepts memalign (m3b, maxim) * Syntax fix: added missing va_end()s. Helps non-gcc compiling (etune) * Fixed a few coredumper bugs: race condition after PTRACE_DETACH, ignore non-aligned stackframe pointers (markus, menage) * 64-bit cleanup, especially for spinlock code (etune) and mmap (sanjay) * Better support for finding threads in linux (markus) * tcmalloc now tracks those stack traces that allocate memory (sanjay) * Work around a weird setspecific problem (sanjay) * Fix tcmalloc overflow problems when an alloc is close to 2G/4G (sanjay) git-svn-id: http://gperftools.googlecode.com/svn/trunk@15 6b5cf1ce-ec42-a296-1ba9-69fdba395a50
Diffstat (limited to 'src/malloc_extension.cc')
-rw-r--r--src/malloc_extension.cc84
1 files changed, 62 insertions, 22 deletions
diff --git a/src/malloc_extension.cc b/src/malloc_extension.cc
index 8ca58a7..1a42e6e 100644
--- a/src/malloc_extension.cc
+++ b/src/malloc_extension.cc
@@ -108,6 +108,10 @@ void** MallocExtension::ReadStackTraces() {
return NULL;
}
+void** MallocExtension::ReadHeapGrowthStackTraces() {
+ return NULL;
+}
+
// The current malloc extension object. We also keep a pointer to
// the default implementation so that the heap-leak checker does not
// complain about a memory leak.
@@ -178,9 +182,37 @@ struct StackTraceEqual {
typedef HASH_NAMESPACE::hash_set<void**, StackTraceHash, StackTraceEqual> StackTraceTable;
-void DebugStringWriter(const char* str, void* arg) {
- string* result = reinterpret_cast<string*>(arg);
- *result += str;
+void PrintHeader(string* result, const char* label, void** entries) {
+ // Compute the total count and total size
+ uintptr_t total_count = 0;
+ uintptr_t total_size = 0;
+ for (void** entry = entries; Count(entry) != 0; entry += 3 + Depth(entry)) {
+ total_count += Count(entry);
+ total_size += Size(entry);
+ }
+
+ char buf[200];
+ snprintf(buf, sizeof(buf),
+ "heap profile: %6lld: %8lld [%6lld: %8lld] @ %s\n",
+ static_cast<long long>(total_count),
+ static_cast<long long>(total_size),
+ static_cast<long long>(total_count),
+ static_cast<long long>(total_size),
+ label);
+ *result += buf;
+}
+
+void PrintStackEntry(string* result, void** entry) {
+ char buf[100];
+ snprintf(buf, sizeof(buf), "%6d: %8d [%6d: %8d] @",
+ int(Count(entry)), int(Size(entry)),
+ int(Count(entry)), int(Size(entry)));
+ *result += buf;
+ for (int i = 0; i < Depth(entry); i++) {
+ snprintf(buf, sizeof(buf), " %p", PC(entry, i));
+ *result += buf;
+ }
+ *result += "\n";
}
}
@@ -188,18 +220,16 @@ void DebugStringWriter(const char* str, void* arg) {
void MallocExtension::GetHeapSample(string* result) {
void** entries = ReadStackTraces();
if (entries == NULL) {
- *result += "this malloc implementation does not support sampling\n";
+ *result += "This malloc implementation does not support sampling.\n"
+ "As of 2005/01/26, only tcmalloc supports sampling, and you\n"
+ "are probably running a binary that does not use tcmalloc.\n";
return;
}
// Group together all entries with same stack trace
StackTraceTable table;
- int total_count = 0;
- int total_size = 0;
for (void** entry = entries; Count(entry) != 0; entry += 3 + Depth(entry)) {
StackTraceTable::iterator iter = table.find(entry);
- total_count += Count(entry);
- total_size += Size(entry);
if (iter == table.end()) {
// New occurrence
table.insert(entry);
@@ -210,27 +240,37 @@ void MallocExtension::GetHeapSample(string* result) {
}
}
- char buf[100];
- snprintf(buf, sizeof(buf), "heap profile: %6d: %8d [%6d: %8d] @\n",
- total_count, total_size, total_count, total_size);
- *result += buf;
+ PrintHeader(result, "heap", entries);
for (StackTraceTable::iterator iter = table.begin();
iter != table.end();
++iter) {
- void** entry = *iter;
- snprintf(buf, sizeof(buf), "%6d: %8d [%6d: %8d] @",
- int(Count(entry)), int(Size(entry)),
- int(Count(entry)), int(Size(entry)));
- *result += buf;
- for (int i = 0; i < Depth(entry); i++) {
- snprintf(buf, sizeof(buf), " %p", PC(entry, i));
- *result += buf;
- }
- *result += "\n";
+ PrintStackEntry(result, *iter);
}
// TODO(menage) Get this working in google-perftools
//DumpAddressMap(DebugStringWriter, result);
+}
+
+void MallocExtension::GetHeapGrowthStacks(std::string* result) {
+ void** entries = ReadHeapGrowthStackTraces();
+ if (entries == NULL) {
+ *result += "This malloc implementation does not support "
+ "ReadHeapGrowhStackTraces().\n"
+ "As of 2005/09/27, only tcmalloc supports this, and you\n"
+ "are probably running a binary that does not use tcmalloc.\n";
+ return;
+ }
+ // Do not canonicalize the stack entries, so that we get a
+ // time-ordered list of stack traces, which may be useful if the
+ // client wants to focus on the latest stack traces.
+
+ PrintHeader(result, "growth", entries);
+ for (void** entry = entries; Count(entry) != 0; entry += 3 + Depth(entry)) {
+ PrintStackEntry(result, entry);
+ }
delete[] entries;
+
+ // TODO(menage) Get this working in google-perftools
+ //DumpAddressMap(DebugStringWriter, result);
}