diff --git a/mozilla/tools/leaky/Makefile.in b/mozilla/tools/leaky/Makefile.in index 3267671564c..2f6e54977f8 100644 --- a/mozilla/tools/leaky/Makefile.in +++ b/mozilla/tools/leaky/Makefile.in @@ -41,6 +41,15 @@ LIBS = \ -liberty \ $(NULL) +RESOURCES = \ + leaky.css \ + leaky.js \ + open.gif \ + open-over.gif \ + close.gif \ + close-over.gif \ + $(NULL) + # Stuff to build the library used to wrap malloc LIBMALLOC_CPPSRCS = libmalloc.cpp LIBMALLOC_OBJECTS = $(LIBMALLOC_CPPSRCS:.cpp=.o) @@ -53,10 +62,27 @@ LIBPRELOAD = libpreload.so # include $(topsrcdir)/config/config.mk -SHARED_LIBRARY = $(LIBMALLOC) $(LIBPRELOAD) +OTHER_LIBRARIES = $(LIBMALLOC) $(LIBPRELOAD) +TARGETS := $(PROGRAM) $(SIMPLE_PROGRAMS) $(OTHER_LIBRARIES) include $(topsrcdir)/config/rules.mk +# Make sure all depends on files that rules.mk doesn't know about. +all:: $(OTHER_LIBRARIES) + +# Make sure install depends on files that rules.mk doesn't know about. +install:: $(OTHER_LIBRARIES) + +# Make sure libs depends on files that rules.mk doesn't know about. +libs:: $(OTHER_LIBRARIES) + +clobber:: + rm -f $(LIBMALLOC_OBJECTS) $(LIBPRELOAD_OBJECTS) + rm -f $(LIBMALLOC) $(LIBPRELOAD) + +clean:: + rm -f $(LIBMALLOC_OBJECTS) $(LIBPRELOAD_OBJECTS) + $(LIBMALLOC): $(LIBMALLOC_OBJECTS) rm -f $@ $(MKSHLIB) -o $@ $(LIBMALLOC_OBJECTS) @@ -68,3 +94,7 @@ test: @echo LIBMALLOC = $(LIBMALLOC) @echo LIBPRELOAD = $(LIBPRELOAD) @echo TARGETS = $(TARGETS) + +install:: + $(INSTALL) -m 555 $(OTHER_LIBRARIES) $(DIST)/lib + $(INSTALL) $(RESOURCES) $(DIST)/bin/res/leaky diff --git a/mozilla/tools/leaky/ShowLibs.cpp b/mozilla/tools/leaky/ShowLibs.cpp index 4e5b4ea54e4..cdf0130347f 100644 --- a/mozilla/tools/leaky/ShowLibs.cpp +++ b/mozilla/tools/leaky/ShowLibs.cpp @@ -20,14 +20,30 @@ // A simple test program that dumps out the loaded shared // libraries. This is essential for leaky to work properly when shared // libraries are used. +static void ShowLibs(struct r_debug* rd) +{ + link_map* map = rd->r_map; + while (NULL != map) { + printf("addr=%08x name=%s prev=%p next=%p\n", map->l_addr, map->l_name, + map->l_prev, map->l_next); + map = map->l_next; + } +} int main(int argc, char** argv) { + void* h = dlopen("/usr/X11R6/lib/libX11.so", RTLD_LAZY); #ifdef linux - link_map* map = _r_debug.r_map; - while (NULL != map) { - printf("addr=%08x name=%s\n", map->l_addr, map->l_name); - map = map->l_next; + printf("Direct r_debug libs:\n"); + ShowLibs(&_r_debug); + + printf("_DYNAMICE r_debug libs:\n"); + ElfW(Dyn)* dp; + for (dp = _DYNAMIC; dp->d_tag != DT_NULL; dp++) { + if (dp->d_tag == DT_DEBUG) { + struct r_debug* rd = (struct r_debug*) dp->d_un.d_ptr; + ShowLibs(rd); + } } #endif return 0; diff --git a/mozilla/tools/leaky/TestLeaky.cpp b/mozilla/tools/leaky/TestLeaky.cpp index a6f1fccf2b6..8f56222bb5f 100644 --- a/mozilla/tools/leaky/TestLeaky.cpp +++ b/mozilla/tools/leaky/TestLeaky.cpp @@ -38,10 +38,70 @@ void s4() cp = cp; } +// Test that mutually recrusive methods don't foul up the graph output +void s6(int recurse); + +void s5(int recurse) +{ + malloc(100); + if (recurse > 0) { + s6(recurse - 1); + } +} + +void s6(int recurse) +{ + malloc(100); + if (recurse > 0) { + s5(recurse - 1); + } +} + +// Test that two pathways through the same node don't cause replicated +// descdendants (A -> B -> C, X -> B -> D shouldn't produce a graph +// that shows A -> B -> D!) + +void C() +{ + malloc(10); +} + +void D() +{ + malloc(10); +} + +void B(int way) +{ + malloc(10); + if (way) { + C(); + C(); + C(); + } else { + D(); + } +} + +void A() +{ + malloc(10); + B(1); +} + +void X() +{ + malloc(10); + B(0); +} + int main() { s1(1, 2); s2(); s3(); s4(); + s5(10); + A(); + X(); } diff --git a/mozilla/tools/leaky/bfd.cpp b/mozilla/tools/leaky/bfd.cpp index 761d48f62b0..180e7f80c36 100644 --- a/mozilla/tools/leaky/bfd.cpp +++ b/mozilla/tools/leaky/bfd.cpp @@ -31,23 +31,23 @@ void leaky::ReadSymbols(const char *aFileName, u_long aBaseAddress) bfd_init (); } - bfd* bfd = bfd_openr(aFileName, NULL); - if (NULL == bfd) { + bfd* lib = bfd_openr(aFileName, NULL); + if (NULL == lib) { return; } char **matching; - if (!bfd_check_format_matches(bfd, bfd_object, &matching)) { - bfd_close(bfd); + if (!bfd_check_format_matches(lib, bfd_object, &matching)) { + bfd_close(lib); return; } asymbol* store; - store = bfd_make_empty_symbol(bfd); + store = bfd_make_empty_symbol(lib); // read mini symbols PTR minisyms; unsigned int size; - long symcount = bfd_read_minisymbols(bfd, kDynamic, &minisyms, &size); + long symcount = bfd_read_minisymbols(lib, kDynamic, &minisyms, &size); int initialSymbols = usefulSymbols; if (NULL == externalSymbols) { @@ -55,17 +55,17 @@ void leaky::ReadSymbols(const char *aFileName, u_long aBaseAddress) numExternalSymbols = 10000; } Symbol* sp = externalSymbols + usefulSymbols; - Symbol* last = externalSymbols + numExternalSymbols; + Symbol* lastSymbol = externalSymbols + numExternalSymbols; // Scan symbols bfd_byte* from = (bfd_byte *) minisyms; bfd_byte* fromend = from + symcount * size; for (; from < fromend; from += size) { asymbol *sym; - sym = bfd_minisymbol_to_symbol(bfd, kDynamic, (const PTR) from, store); + sym = bfd_minisymbol_to_symbol(lib, kDynamic, (const PTR) from, store); symbol_info syminfo; - bfd_get_symbol_info (bfd, sym, &syminfo); + bfd_get_symbol_info (lib, sym, &syminfo); // if ((syminfo.type == 'T') || (syminfo.type == 't')) { const char* nm = bfd_asymbol_name(sym); @@ -74,11 +74,11 @@ void leaky::ReadSymbols(const char *aFileName, u_long aBaseAddress) // sp->name = dnm ? dnm : strdup(nm); sp->Init(nm, syminfo.value + aBaseAddress); sp++; - if (sp >= last) { + if (sp >= lastSymbol) { long n = numExternalSymbols + 10000; externalSymbols = (Symbol*) realloc(externalSymbols, (size_t) (sizeof(Symbol) * n)); - last = externalSymbols + n; + lastSymbol = externalSymbols + n; sp = externalSymbols + numExternalSymbols; numExternalSymbols = n; } @@ -87,7 +87,7 @@ void leaky::ReadSymbols(const char *aFileName, u_long aBaseAddress) } - bfd_close(bfd); + bfd_close(lib); int interesting = sp - externalSymbols; if (!quiet) { diff --git a/mozilla/tools/leaky/config.h b/mozilla/tools/leaky/config.h index 7a6be7d13ed..f59b64f72f9 100644 --- a/mozilla/tools/leaky/config.h +++ b/mozilla/tools/leaky/config.h @@ -12,7 +12,7 @@ #ifndef config_h___ #define config_h___ -#define MAX_STACK_CRAWL 100 +#define MAX_STACK_CRAWL 200 #include diff --git a/mozilla/tools/leaky/leaky.cpp b/mozilla/tools/leaky/leaky.cpp index bd6acb36013..49009c84d32 100644 --- a/mozilla/tools/leaky/leaky.cpp +++ b/mozilla/tools/leaky/leaky.cpp @@ -54,14 +54,14 @@ leaky::leaky() sortByFrequency = FALSE; dumpAll = FALSE; dumpGraph = FALSE; - dumpXML = FALSE; + dumpHTML = FALSE; quiet = FALSE; showAll = FALSE; showAddress = FALSE; stackDepth = 100000; - fd = -1; - base = last = 0; + mappedLogFile = -1; + firstLogEntry = lastLogEntry = 0; buckets = DefaultBuckets; dict = 0; @@ -148,7 +148,7 @@ void leaky::initialize(int argc, char** argv) } break; case 'x': - dumpXML = TRUE; + dumpHTML = TRUE; break; case 'q': quiet = TRUE; @@ -216,14 +216,14 @@ void leaky::open() setupSymbols(progFile); // open up the log file - fd = ::open(logFile, O_RDONLY); - if (fd < 0) { + mappedLogFile = ::open(logFile, O_RDONLY); + if (mappedLogFile < 0) { perror("open"); exit(-1); } off_t size; - base = (malloc_log_entry*) mapFile(fd, PROT_READ, &size); - last = (malloc_log_entry*)((char*)base + size); + firstLogEntry = (malloc_log_entry*) mapFile(mappedLogFile, PROT_READ, &size); + lastLogEntry = (malloc_log_entry*)((char*)firstLogEntry + size); analyze(); @@ -320,7 +320,7 @@ int leaky::excluded(malloc_log_entry* lep) //---------------------------------------------------------------------- -void leaky::displayStackTrace(malloc_log_entry* lep) +void leaky::displayStackTrace(FILE* out, malloc_log_entry* lep) { char** pcp = &lep->pcs[0]; u_int n = (lep->numpcs < stackDepth) ? lep->numpcs : stackDepth; @@ -337,13 +337,13 @@ void leaky::displayStackTrace(malloc_log_entry* lep) symbolName = buf; } if (showAddress) { - printf("%s[%p] ", symbolName, *pcp); + fprintf(out, "%s[%p] ", symbolName, *pcp); } else { - printf("%s ", symbolName); + fprintf(out, "%s ", symbolName); } } - printf("\n"); + fprintf(out, "\n"); } char* typeFromLog[] = { @@ -362,14 +362,14 @@ void leaky::dumpEntryToLog(malloc_log_entry* lep) typeFromLog[lep->type], lep->address, lep->size, lep->oldaddress, lep->numpcs); - displayStackTrace(lep); + displayStackTrace(stdout, lep); } void leaky::dumpLog() { if (showAll) { - malloc_log_entry* lep = base; - while (lep < last) { + malloc_log_entry* lep = firstLogEntry; + while (lep < lastLogEntry) { dumpEntryToLog(lep); lep = (malloc_log_entry*) &lep->pcs[lep->numpcs]; } @@ -393,7 +393,7 @@ void leaky::insertAddress(u_long address, malloc_log_entry* lep) assert(*lepp); if (!quiet) { printf("Address %lx allocated twice\n", address); - displayStackTrace(lep); + displayStackTrace(stdout, lep); } errors++; } else { @@ -407,7 +407,7 @@ void leaky::removeAddress(u_long address, malloc_log_entry* lep) if (!lepp) { if (!quiet) { printf("Free of unallocated %lx\n", address); - displayStackTrace(lep); + displayStackTrace(stdout, lep); } errors++; } else { @@ -417,8 +417,8 @@ void leaky::removeAddress(u_long address, malloc_log_entry* lep) void leaky::analyze() { - malloc_log_entry* lep = base; - while (lep < last) { + malloc_log_entry* lep = firstLogEntry; + while (lep < lastLogEntry) { switch (lep->type) { case malloc_log_malloc: case malloc_log_new: @@ -473,28 +473,39 @@ void leaky::buildLeakGraph() malloc_log_entry* lep; dict->rewind(); while (NULL != (lep = dict->next())) { - Symbol* prevSymbol = NULL; + char** basepcp = &lep->pcs[0]; + char** pcp = &lep->pcs[lep->numpcs - 1]; - // For each pc in the leak - char** pcp = &lep->pcs[0]; - u_int n = (lep->numpcs < stackDepth) ? lep->numpcs : stackDepth; - for (u_int i = 0; i < n; i++, pcp++) { - Symbol* currentSymbol = findSymbol((u_long) *pcp); - if (currentSymbol) { - currentSymbol->leaker = true; - currentSymbol->calls++; - if (i == 0) { - currentSymbol->bytesDirectlyLeaked += lep->size; - } - else { - currentSymbol->childBytesLeaked += lep->size; - } - if (prevSymbol) { - currentSymbol->AddChild(prevSymbol); - prevSymbol->AddParent(currentSymbol); - } + // Find root for this allocation + Symbol* sym = findSymbol((u_long) *pcp); + TreeNode* node = sym->root; + if (!node) { + displayStackTrace(stderr, lep); + sym->root = node = new TreeNode(sym); + } + pcp--; + + // Build tree underneath the root + for (; pcp >= basepcp; pcp--) { + // Share nodes in the tree until there is a divergence + sym = findSymbol((u_long) *pcp); + if (!sym) { + break; } - prevSymbol = currentSymbol; + TreeNode* nextNode = node->GetDirectDescendant(sym); + if (!nextNode) { + // Make a new node at the point of divergence + nextNode = node->AddDescendant(sym); + } + + if (pcp == basepcp) { + nextNode->bytesLeaked += lep->size; + } + else { + node->descendantBytesLeaked += lep->size; + } + + node = nextNode; } } } @@ -502,7 +513,7 @@ void leaky::buildLeakGraph() Symbol* leaky::findLeakGraphRoot(Symbol* aStart, Symbol* aEnd) { while (aStart < aEnd) { - if (aStart->leaker && !aStart->parents) { + if (aStart->root) { return aStart; } aStart++; @@ -512,183 +523,118 @@ Symbol* leaky::findLeakGraphRoot(Symbol* aStart, Symbol* aEnd) void leaky::dumpLeakGraph() { - if (dumpXML) { -#ifdef USE_XML - printf("\n"); - printf("\n"); - printf("\n"); - printf("\n"); - printf("\n"); - printf("Key:\n"); - printf("Bytes directly leaked\n"); - printf("Bytes leaked by descendants\n"); -#else + if (dumpHTML) { printf("Leaky Graph\n"); - printf("\n"); - printf("\n"); + printf("\n"); + printf("\n"); printf("
\n"); printf("Key:
\n"); printf("Bytes directly leaked
\n"); printf("Bytes leaked by descendants
\n"); -#endif } Symbol* base = externalSymbols; Symbol* end = externalSymbols + usefulSymbols; while (base < end) { - Symbol* root = findLeakGraphRoot(base, end); - if (!root) break; - if (root->NotDumped()) { - root->SetDumped(); - dumpLeakTree(root, 0, true); - } - base = root + 1; + Symbol* sym = findLeakGraphRoot(base, end); + if (!sym) break; + dumpLeakTree(sym->root, 0); + base = sym + 1; } - if (dumpXML) { -#ifdef USE_XML - printf("
\n"); -#else + if (dumpHTML) { printf("\n"); -#endif } } -void leaky::dumpLeakTree(Symbol* aSymbol, int aIndent, bool aEven) +void leaky::dumpLeakTree(TreeNode* aNode, int aIndent) { -#if 0 - float avgBytesLeaked = - (float) (aSymbol->bytesDirectlyLeaked + aSymbol->childBytesLeaked) / - (float) aSymbol->calls; -#endif - - bool haveVisibleDescendants = false; - SymbolNode* node = aSymbol->children; - while (node) { - Symbol* kid = node->symbol; - if (kid && kid->NotDumped()) { - haveVisibleDescendants = true; - break; - } - node = node->next; - } - - if (dumpXML) { -#ifdef USE_XML - printf("", aEven ? "e" : "o"); - if (haveVisibleDescendants) { - printf("" + Symbol* sym = aNode->symbol; + if (dumpHTML) { + printf("
\n"); + if (aNode->HasDescendants()) { + printf("", aIndent > 1 ? "close" : "open"); } - printf("%s%ld%ld\n", - aSymbol->name, - aSymbol->bytesDirectlyLeaked, - aSymbol->childBytesLeaked); -#else - printf("
\n", aEven ? 'e' : 'o'); - if (haveVisibleDescendants) { - printf("", - aIndent > 1 ? "close" : "open"); - } - printf("%s%ld%ld\n", - aSymbol->name, - aSymbol->bytesDirectlyLeaked, - aSymbol->childBytesLeaked); -#endif + printf("%s%ld", + sym->name, + aNode->bytesLeaked); + printf("%ld\n", + aNode->descendantBytesLeaked); } else { indentBy(aIndent); printf("%s bytesLeaked=%ld (%ld from kids)\n", - aSymbol->name, - aSymbol->bytesDirectlyLeaked, - aSymbol->childBytesLeaked); + sym->name, + aNode->bytesLeaked, + aNode->descendantBytesLeaked); } - node = aSymbol->children; + TreeNode* node = aNode->descendants; int kidNum = 0; while (node) { - Symbol* kid = node->symbol; - if (kid && kid->NotDumped()) { - kid->SetDumped(); - dumpLeakTree(kid, aIndent + 1, 0 == (kidNum & 1)); - kidNum++; - } - node = node->next; + sym = node->symbol; + dumpLeakTree(node, aIndent + 1); + kidNum++; + node = node->nextSibling; } - if (dumpXML) { -#ifdef USE_XML - printf(""); -#else + if (dumpHTML) { printf("
"); -#endif } } //---------------------------------------------------------------------- -SymbolNode* SymbolNode::freeList; +TreeNode* TreeNode::freeList; -void* SymbolNode::operator new(size_t size) +void* TreeNode::operator new(size_t size) { if (!freeList) { - SymbolNode* newNodes = (SymbolNode*) new char[sizeof(SymbolNode) * 5000]; + TreeNode* newNodes = (TreeNode*) new char[sizeof(TreeNode) * 5000]; if (!newNodes) { return NULL; } - SymbolNode* n = newNodes; - SymbolNode* end = newNodes + 5000 - 1; + TreeNode* n = newNodes; + TreeNode* end = newNodes + 5000 - 1; while (n < end) { - n->next = n + 1; + n->nextSibling = n + 1; n++; } - n->next = NULL; + n->nextSibling = NULL; freeList = newNodes; } - SymbolNode* rv = freeList; - freeList = rv->next; + TreeNode* rv = freeList; + freeList = rv->nextSibling; return (void*) rv; } -void SymbolNode::operator delete(void* ptr) +void TreeNode::operator delete(void* ptr) { - SymbolNode* node = (SymbolNode*) ptr; + TreeNode* node = (TreeNode*) ptr; if (node) { - node->next = freeList; + node->nextSibling = freeList; freeList = node; } } -//---------------------------------------------------------------------- - -void Symbol::Init(const char* aName, u_long aAddress) +TreeNode* TreeNode::GetDirectDescendant(Symbol* aSymbol) { - name = aName ? strdup(aName) : ""; - address = aAddress; - dumped = false; - leaker = false; - calls = 0; - parents = NULL; - children = NULL; - bytesDirectlyLeaked = 0; - childBytesLeaked = 0; -} - -void Symbol::AddParent(Symbol* aParent) -{ - SymbolNode* node = new SymbolNode(aParent); - if (node) { - node->next = parents; - parents = node; + TreeNode* node = descendants; + while (node) { + if (node->symbol == aSymbol) { + return node; + } + node = node->nextSibling; } + return NULL; } -void Symbol::AddChild(Symbol* aChild) +TreeNode* TreeNode::AddDescendant(Symbol* aSymbol) { - SymbolNode* node = new SymbolNode(aChild); - if (node) { - node->next = children; - children = node; - } + TreeNode* node = new TreeNode(aSymbol); + node->nextSibling = descendants; + descendants = node; + return node; } - diff --git a/mozilla/tools/leaky/leaky.css b/mozilla/tools/leaky/leaky.css index ec4b84221bc..a4c832aff32 100644 --- a/mozilla/tools/leaky/leaky.css +++ b/mozilla/tools/leaky/leaky.css @@ -1,51 +1,53 @@ -root { - display: block; - margin: 1em 1em; +body { + background-color: white; line-height: 1.1; + margin: 1em; font-size: 10pt; font-family: "Arial", "Times New Roman", "Times Roman", serif; } -root > n, root > n > n, root > n > n > n { - display: block; -} - body > .n, body > .n > .n, body > .n > .n > .n { display: block; } -key, .key { +.key { display: block; margin: 1em; border: 2px solid green; + width: 50%; + margin: 0 auto 1em auto; font-size: 130%; } -key b, key k, .key .b, .key .d { margin: 0 0 0 2em; padding: 0; } -n, .n { +.key .b, .key .d { + margin: 0 0 0 2em; + padding: 0; +} + +.n { display: none; - margin: 0 1em; + margin: 0 0 0 1em; white-space: nowrap; } -n.e, .n.e { - background-color: orange; +.n.e { + background-color: rgb(180,180,180); } -s, .s { +.s { display: inline; margin-left: 5px; } -b, .b { +.b { display: inline; background-color: yellow; - margin: 0 1em; - padding: 0 1em; + margin: 0 1em 0 1em; + padding: 0 5px; } -k, .d { +.d { display: inline; background-color: khaki; - padding: 0 1em; + padding: 0 5px; } diff --git a/mozilla/tools/leaky/leaky.h b/mozilla/tools/leaky/leaky.h index c2921afbf55..21c27e2568f 100644 --- a/mozilla/tools/leaky/leaky.h +++ b/mozilla/tools/leaky/leaky.h @@ -15,6 +15,7 @@ #include "config.h" #include +#include #include #include "dict.h" #include "strset.h" @@ -23,43 +24,44 @@ typedef unsigned int u_int; struct Symbol; -struct SymbolNode { - SymbolNode(Symbol* aSymbol) { +struct TreeNode { + TreeNode(Symbol* aSymbol) { symbol = aSymbol; - next = NULL; + nextSibling = NULL; + descendants = NULL; } + TreeNode* GetDirectDescendant(Symbol* aSymbol); + + bool HasDescendants() const { + return NULL != descendants; + } + + TreeNode* AddDescendant(Symbol* aSymbol); + + TreeNode* descendants; + TreeNode* nextSibling; + Symbol* symbol; + + u_long bytesLeaked; + u_long descendantBytesLeaked; + void* operator new(size_t size); void operator delete(void* ptr); - Symbol* symbol; - SymbolNode* next; - - static SymbolNode* freeList; + static TreeNode* freeList; }; struct Symbol { char* name; u_long address; - bool dumped; - bool leaker; - u_long calls; - SymbolNode* parents; - SymbolNode* children; - u_long bytesDirectlyLeaked; - u_long childBytesLeaked; + TreeNode* root; - bool NotDumped() const { - return 0 == dumped; + void Init(const char* aName, u_long aAddress) { + name = aName ? strdup(aName) : ""; + address = aAddress; + root = NULL; } - - void SetDumped() { - dumped = 1; - } - - void Init(const char* aName, u_long aAddress); - void AddParent(Symbol* aParent); - void AddChild(Symbol* aChild); }; struct LoadMapEntry { @@ -82,15 +84,15 @@ struct leaky { int sortByFrequency; int dumpAll; int dumpGraph; - int dumpXML; + int dumpHTML; int quiet; int showAll; int showAddress; u_int stackDepth; - int fd; - malloc_log_entry* base; - malloc_log_entry* last; + int mappedLogFile; + malloc_log_entry* firstLogEntry; + malloc_log_entry* lastLogEntry; u_int buckets; MallocDict* dict; @@ -128,7 +130,7 @@ struct leaky { void insertAddress(u_long address, malloc_log_entry* lep); void removeAddress(u_long address, malloc_log_entry* lep); - void displayStackTrace(malloc_log_entry* lep); + void displayStackTrace(FILE* out, malloc_log_entry* lep); void ReadSymbols(const char* fileName, u_long aBaseAddress); void ReadSharedLibrarySymbols(); @@ -139,7 +141,7 @@ struct leaky { void buildLeakGraph(); Symbol* findLeakGraphRoot(Symbol* aStart, Symbol* aEnd); void dumpLeakGraph(); - void dumpLeakTree(Symbol* aRoot, int aIndent, bool aEven); + void dumpLeakTree(TreeNode* aNode, int aIndent); static void indentBy(int aCount) { while (--aCount >= 0) fputs(" ", stdout); diff --git a/mozilla/tools/leaky/libmalloc.cpp b/mozilla/tools/leaky/libmalloc.cpp index d8704d85f7b..fb20d908937 100644 --- a/mozilla/tools/leaky/libmalloc.cpp +++ b/mozilla/tools/leaky/libmalloc.cpp @@ -97,6 +97,10 @@ static void DumpAddressMap() mme.address = map->l_addr; write(mfd, &mme, sizeof(mme)); write(mfd, map->l_name, mme.nameLen); +#if 0 + write(1, map->l_name, mme.nameLen); + write(1, "\n", 1); +#endif } map = map->l_next; }