diff options
author | csilvers <csilvers@6b5cf1ce-ec42-a296-1ba9-69fdba395a50> | 2007-03-22 04:44:18 +0000 |
---|---|---|
committer | csilvers <csilvers@6b5cf1ce-ec42-a296-1ba9-69fdba395a50> | 2007-03-22 04:44:18 +0000 |
commit | ee5805f1296f8546c16f90d5427efa347a5f7338 (patch) | |
tree | 38870545181491e1e98bd7cd901d8d276d1bc223 /src/malloc_extension.cc | |
parent | bc455d7b63949fab94ed9518d277866e95f08768 (diff) | |
download | gperftools-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.cc | 84 |
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); } |