michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef __leaky_h_ michael@0: #define __leaky_h_ michael@0: michael@0: #include "config.h" michael@0: #include michael@0: #include michael@0: #include michael@0: #include "libmalloc.h" michael@0: #include "strset.h" michael@0: #include "intcnt.h" michael@0: michael@0: typedef unsigned int u_int; michael@0: michael@0: struct Symbol; michael@0: struct leaky; michael@0: michael@0: class FunctionCount : public IntCount michael@0: { michael@0: public: michael@0: void printReport(FILE *fp, leaky *lk, int parent, int total); michael@0: }; michael@0: michael@0: struct Symbol { michael@0: char* name; michael@0: u_long address; michael@0: int timerHit; michael@0: FunctionCount cntP, cntC; michael@0: michael@0: int regChild(int id) {return cntC.countAdd(id, 1);} michael@0: int regParrent(int id) {return cntP.countAdd(id, 1);} michael@0: void regClear() {cntC.clear(); cntP.clear();} michael@0: michael@0: Symbol() : timerHit(0) {} michael@0: void Init(const char* aName, u_long aAddress) { michael@0: name = aName ? strdup(aName) : (char *)""; michael@0: address = aAddress; michael@0: } michael@0: }; michael@0: michael@0: struct LoadMapEntry { michael@0: char* name; // name of .so michael@0: u_long address; // base address where it was mapped in michael@0: LoadMapEntry* next; michael@0: }; michael@0: michael@0: struct leaky { michael@0: leaky(); michael@0: ~leaky(); michael@0: michael@0: void initialize(int argc, char** argv); michael@0: void open(char *arg); michael@0: michael@0: char* applicationName; michael@0: int logFileIndex; michael@0: int numLogFiles; michael@0: char* progFile; michael@0: FILE* outputfd; michael@0: michael@0: bool quiet; michael@0: bool showAddress; michael@0: bool showThreads; michael@0: bool cleo; michael@0: u_int stackDepth; michael@0: int onlyThread; michael@0: char* output_dir; michael@0: michael@0: int mappedLogFile; michael@0: malloc_log_entry* firstLogEntry; michael@0: malloc_log_entry* lastLogEntry; michael@0: michael@0: int stacks; michael@0: michael@0: int sfd; michael@0: Symbol** externalSymbols; michael@0: Symbol** lastSymbol; michael@0: int usefulSymbols; michael@0: int numExternalSymbols; michael@0: StrSet exclusions; michael@0: u_long lowestSymbolAddr; michael@0: u_long highestSymbolAddr; michael@0: michael@0: LoadMapEntry* loadMap; michael@0: michael@0: bool collect_last; michael@0: int collect_start; michael@0: int collect_end; michael@0: michael@0: StrSet roots; michael@0: StrSet includes; michael@0: michael@0: void usageError(); michael@0: michael@0: void LoadMap(); michael@0: michael@0: void analyze(int thread); michael@0: michael@0: void dumpEntryToLog(malloc_log_entry* lep); michael@0: michael@0: void insertAddress(u_long address, malloc_log_entry* lep); michael@0: void removeAddress(u_long address, malloc_log_entry* lep); michael@0: michael@0: void displayStackTrace(FILE* out, malloc_log_entry* lep); michael@0: michael@0: Symbol ** ExtendSymbols(int num); michael@0: void ReadSymbols(const char* fileName, u_long aBaseAddress); michael@0: void ReadSharedLibrarySymbols(); michael@0: void setupSymbols(const char* fileName); michael@0: Symbol* findSymbol(u_long address); michael@0: bool excluded(malloc_log_entry* lep); michael@0: bool included(malloc_log_entry* lep); michael@0: const char* indexToName(int idx) {return externalSymbols[idx]->name;} michael@0: michael@0: private: michael@0: void generateReportHTML(FILE *fp, int *countArray, int count, int thread); michael@0: int findSymbolIndex(u_long address); michael@0: }; michael@0: michael@0: #endif /* __leaky_h_ */