Back to index

lightning-sunbird  0.9+nobinonly
leaky.h
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is mozilla.org code.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Kipp E.B. Hickman.
00018  * Portions created by the Initial Developer are Copyright (C) 1999
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 #ifndef __leaky_h_
00038 #define __leaky_h_
00039 
00040 #include "config.h"
00041 #include <stdio.h>
00042 #include <string.h>
00043 #include <sys/types.h>
00044 #include "dict.h"
00045 #include "strset.h"
00046 #include "xpcom-config.h" // for CPP_NEW_THROW
00047 
00048 typedef unsigned int u_int;
00049 
00050 struct Symbol;
00051 
00052 struct TreeNode {
00053   TreeNode(Symbol* aSymbol) {
00054     symbol = aSymbol;
00055     nextSibling = NULL;
00056     descendants = NULL;
00057     nextRoot = NULL;
00058     bytesLeaked = 0;
00059     descendantBytesLeaked = 0;
00060   }
00061 
00062   TreeNode* GetDirectDescendant(Symbol* aSymbol);
00063 
00064   bool HasDescendants() const {
00065     return NULL != descendants;
00066   }
00067 
00068   TreeNode* AddDescendant(Symbol* aSymbol);
00069 
00070   TreeNode* descendants;
00071   TreeNode* nextSibling;
00072   TreeNode* nextRoot;
00073   Symbol* symbol;
00074 
00075   u_long bytesLeaked;
00076   u_long descendantBytesLeaked;
00077 
00078   void* operator new(size_t size) CPP_THROW_NEW ;
00079   void operator delete(void* ptr);
00080 
00081   static TreeNode* freeList;
00082 };
00083 
00084 struct Symbol {
00085   char* name;
00086   u_long address;
00087   TreeNode* root;
00088 
00089   void Init(const char* aName, u_long aAddress) {
00090     name = aName ? strdup(aName) : (char *)"";
00091     address = aAddress;
00092     root = NULL;
00093   }
00094 };
00095 
00096 struct LoadMapEntry {
00097   char* name;               // name of .so
00098   u_long address;           // base address where it was mapped in
00099   LoadMapEntry* next;
00100 };
00101 
00102 struct leaky {
00103   leaky();
00104   ~leaky();
00105 
00106   void initialize(int argc, char** argv);
00107   void open();
00108 
00109   char*  applicationName;
00110   char*  logFile;
00111   char*  progFile;
00112 
00113   int   dumpLeaks;
00114   int   dumpGraph;
00115   int   dumpHTML;
00116   int   quiet;
00117   int   dumpEntireLog;
00118   int   showAddress;
00119   bool  dumpRefcnts;
00120   u_int  stackDepth;
00121 
00122   int   mappedLogFile;
00123   malloc_log_entry* firstLogEntry;
00124   malloc_log_entry* lastLogEntry;
00125   u_int  buckets;
00126   MallocDict*  dict;
00127   MallocDict*  refcntDict;
00128 
00129   u_long  mallocs;
00130   u_long  reallocs;
00131   u_long  frees;
00132   u_long  totalMalloced;
00133   u_long  errors;
00134   u_long  totalLeaked;
00135 
00136   int sfd;
00137   Symbol* externalSymbols;
00138   u_int usefulSymbols;
00139   u_int numExternalSymbols;
00140   StrSet exclusions;
00141   u_long lowestSymbolAddr;
00142   u_long highestSymbolAddr;
00143 
00144   LoadMapEntry* loadMap;
00145 
00146   TreeNode* rootList;
00147 
00148   StrSet roots;
00149   StrSet includes;
00150 
00151   void usageError();
00152 
00153   void LoadMap();
00154 
00155   void analyze();
00156 
00157   void dumpLog();
00158   void dumpEntryToLog(malloc_log_entry* lep);
00159 
00160 #if 0
00161   void dumpToTree();
00162   void dumpEntryToTree(FILE* fp, malloc_log_entry* lep);
00163 #endif
00164 
00165   void insertAddress(u_long address, malloc_log_entry* lep);
00166   void removeAddress(u_long address, malloc_log_entry* lep);
00167 
00168   void displayStackTrace(FILE* out, malloc_log_entry* lep);
00169 
00170   void ReadSymbols(const char* fileName, u_long aBaseAddress);
00171   void ReadSharedLibrarySymbols();
00172   void setupSymbols(const char* fileName);
00173   Symbol* findSymbol(u_long address);
00174   bool excluded(malloc_log_entry* lep);
00175   bool included(malloc_log_entry* lep);
00176 
00177   void buildLeakGraph();
00178   Symbol* findLeakGraphRoot(Symbol* aStart, Symbol* aEnd);
00179   void dumpLeakGraph();
00180   void dumpLeakTree(TreeNode* aNode, int aIndent);
00181 
00182   bool ShowThisEntry(malloc_log_entry* lep);
00183 
00184   bool IsRefcnt(malloc_log_entry* lep) const {
00185     return (lep->type == malloc_log_addref) ||
00186       (lep->type == malloc_log_release);
00187   }
00188 
00189   static void indentBy(int aCount) {
00190     while (--aCount >= 0) fputs("  ", stdout);
00191   }
00192 };
00193 
00194 #endif /* __leaky_h_ */