Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "LeakChecker.h"
- #include "stdio.h"
- #include "stdlib.h"
- #include <pthread.h>
- #include <assert.h>
- #include <vector>
- #include <set>
- #include <list>
- #include <algorithm>
- #include <execinfo.h>
- #include <cxxabi.h>
- //#include <QtCore/qDebug>
- //#include "//qDebugTrace.h"
- #define MAX_STACKSIZE 20
- #define MAX__SYMBOL_SIZE 200
- //#define LEAK_REPORT_FILE_NAME "/var/opt/bosch/dynamic/media/LOG/leak.log"
- #define LEAK_REPORT_FILE_NAME "/home/sunny/CodeTest/log/leak.log"
- //IMPLEMENT_//qDebug_OBJECT(LeakChecker,"LeakChecker.txt");
- using namespace std;
- struct MemInfo{
- int iSize;
- void* pAddress;
- void* stackTrace[MAX_STACKSIZE];
- int iStackSize;
- bool bIsLeak;
- bool bIsArray;
- bool bMarkDone;
- MemInfo* pNext;
- };
- struct DeletedMemInfo{
- void *pAddress;
- bool bIsArray;
- DeletedMemInfo* pNext;
- };
- pthread_mutex_t mutexNew;
- pthread_mutex_t mutexDelete;
- MemInfo *pNewListStart=NULL;
- MemInfo *pNewListLast=NULL;
- DeletedMemInfo *pFreedListStart = NULL;
- DeletedMemInfo *pFreedListLast=NULL;
- list<void*> arrFreed;
- set<void*> setUniqueAddressList;
- char** strings;
- unsigned int iFreeListSize = 0;
- unsigned int iTotalLeaksFound = 0;
- LeakChecker LeakChecker::m_globalLeakChecker;
- void InitDeletedMemInfo(DeletedMemInfo *pDeletedMemInfo) {
- pDeletedMemInfo->pAddress = NULL;
- pDeletedMemInfo->pNext = NULL;
- }
- void InitMemInfo(MemInfo *pMemInfo) {
- pMemInfo->iSize = 0;
- pMemInfo->pAddress = 0;
- pMemInfo->iStackSize = 0;
- pMemInfo->pNext = 0;
- pMemInfo->bIsLeak = false;
- pMemInfo->bMarkDone = false;
- }
- void* Allocate(int size, bool bIsArray) {
- void *p=malloc(size);
- pthread_mutex_lock (&mutexNew);
- if(pNewListStart) {
- MemInfo *pMemInfoNode = (MemInfo*) malloc(sizeof(MemInfo));
- InitMemInfo(pMemInfoNode);
- pMemInfoNode->iStackSize = backtrace (pMemInfoNode->stackTrace, MAX_STACKSIZE);
- pMemInfoNode->pAddress = p;
- pMemInfoNode->iSize = size;
- pMemInfoNode->bIsArray = bIsArray;
- pNewListLast->pNext = pMemInfoNode;
- pNewListLast = pMemInfoNode;
- }
- pthread_mutex_unlock(&mutexNew);
- return p;
- }
- void Deallocate(void *p, bool bIsArray) {
- pthread_mutex_lock (&mutexDelete);
- if(pFreedListLast) {
- DeletedMemInfo* pMemInfoNode = (DeletedMemInfo*) malloc( sizeof(DeletedMemInfo));
- InitDeletedMemInfo(pMemInfoNode);
- pMemInfoNode->pAddress = p;
- pMemInfoNode->bIsArray = bIsArray;
- pFreedListLast->pNext = pMemInfoNode;
- pFreedListLast=pMemInfoNode;
- iFreeListSize++;
- }
- pthread_mutex_unlock(&mutexDelete);
- free(p);
- }
- void* operator new (size_t size) {
- return Allocate(size, false);
- }
- void* operator new[] (size_t size) {
- return Allocate(size, true);
- }
- void operator delete[](void *p) {
- Deallocate(p, true);
- }
- void operator delete (void *p) {
- Deallocate(p, false);
- }
- void freeAllTheMemory(MemInfo *pLocalNewListStart) {
- MemInfo* pNode = pLocalNewListStart->pNext;
- while(pNode) {
- MemInfo *pCurrent = pNode;
- pNode = pNode->pNext;
- free(pCurrent);
- }
- arrFreed.clear();
- }
- void CreateVectorFromList(DeletedMemInfo* pLocalDeletedStart) {
- pLocalDeletedStart = pLocalDeletedStart->pNext;
- while(pLocalDeletedStart) {
- arrFreed.push_back(pLocalDeletedStart->pAddress);
- DeletedMemInfo* pCurrentMemInfo = pLocalDeletedStart;
- pLocalDeletedStart = pLocalDeletedStart->pNext;
- free(pCurrentMemInfo);
- }
- }
- bool searchAndRemove(void *pAddress) {
- list<void*>::iterator it;
- for ( it=arrFreed.begin() ; it != arrFreed.end(); it++ ) {
- if(*it == pAddress) {
- arrFreed.erase(it);
- return true;
- }
- }
- return false;
- }
- void GetAllLeaks(MemInfo *pLocalNewStart) {
- MemInfo* pNode = pLocalNewStart->pNext;
- //sort(arrFreed.begin(), arrFreed.end());
- int iCount = 0;
- while(pNode) {
- iCount++;
- if(!searchAndRemove(pNode->pAddress)) {
- pNode->bIsLeak = true;
- iTotalLeaksFound++;
- }
- pNode = pNode->pNext;
- }
- //qDebug("GetAllLeaks %d", iCount);
- }
- void CreateUniqueLeakAddessVector(MemInfo* /*pLocalNewStart*/) {
- // pLocalNewStart = pLocalNewStart->pNext;
- // while(pLocalNewStart) {
- // if(pLocalNewStart->bIsLeak) {
- // for(int i=0; i < pLocalNewStart->iStackSize; i++ ) {
- // setUniqueAddressList.insert(pLocalNewStart->stackTrace[i]);
- // }
- // }
- // pLocalNewStart = pLocalNewStart->pNext;
- // }
- }
- void printfSymbolsWithAddresses(vector<void*> &arrSymbolAddress) {
- for(unsigned i=0; i<arrSymbolAddress.size(); i++) {
- printf("%p %s", arrSymbolAddress[i], strings[i]);
- }
- }
- void GetSymbolNames() {
- // vector<void*> arrSymbolAddress;
- // for (set<void*>::iterator it=setUniqueAddressList.begin(); it!=setUniqueAddressList.end(); it++)
- // arrSymbolAddress.push_back(*it);
- // strings = backtrace_symbols(arrSymbolAddress.data(), arrSymbolAddress.size());
- // printfSymbolsWithAddresses(arrSymbolAddress);
- }
- void getMangledSymbolName(char* strSymbolName, int *iSymbolStart , int *iSymbolLength,
- int *iAddressStart, int *iAddressLength) {
- *iSymbolStart = *iSymbolLength = *iAddressStart = *iAddressLength = 0;
- for(int i=0; strSymbolName[i] != '\0'; i++) {
- if(strSymbolName[i] == '(') {
- strSymbolName[i] = NULL;
- *iSymbolStart = i+1;
- } else if( strSymbolName[i] == '+' ) {
- if(*iSymbolStart != 0) {
- *iSymbolLength = i - *iSymbolStart;
- strSymbolName[i] = NULL;
- continue;
- }
- } else if ( strSymbolName[i] == '[') {
- *iAddressStart = i;
- } else if(strSymbolName[i] == ']') {
- if(*iAddressStart != 0) {
- *iAddressLength = i - *iAddressStart;
- }
- }
- }
- }
- void printOutput(MemInfo *pLocalNewStart) {
- //qDebug("Start void printOutput MemInfo *pLocalNewStart %d", iTotalLeaksFound);
- pLocalNewStart = pLocalNewStart->pNext;
- FILE *fp = fopen(LEAK_REPORT_FILE_NAME, "w");
- if(!fp) {
- //qDebug("unable to open file");
- return;
- } else {
- //qDebug("File Open Done");
- }
- int iCurrentCount = 0;
- while(pLocalNewStart) {
- if(pLocalNewStart->bIsLeak) {
- strings = backtrace_symbols(pLocalNewStart->stackTrace, pLocalNewStart->iStackSize);
- fprintf(fp,"Size = %d Pointer = %p %d outof %d \n", pLocalNewStart->iSize, pLocalNewStart->pAddress, iCurrentCount, iTotalLeaksFound);
- iCurrentCount++;
- //qDebug("Size = %d Pointer = %p %d outof %d \n", pLocalNewStart->iSize, pLocalNewStart->pAddress, iCurrentCount, iTotalLeaksFound);
- for(int i=2; i<pLocalNewStart->iStackSize; i++) {
- //printf("%s\n", strings[i]);
- //fflush(stdout);
- char * strName = strings[i];
- //fprintf(fp, "%s\n", strName);
- int iSymbolStart, iSymbolLength, iAddressStart, iAddressLength;
- getMangledSymbolName(strName, &iSymbolStart, &iSymbolLength,
- &iAddressStart, &iAddressLength);
- if(iSymbolStart != 0) {
- fprintf(fp,"%s", strName);
- }
- if(iSymbolLength == 0) {
- fprintf(fp," [No Symbol Availale]");
- } else {
- char *strDemangledSymbol = (char*) malloc(MAX__SYMBOL_SIZE);
- size_t iDemangledSymbolSize = MAX__SYMBOL_SIZE;
- int iStatus = 0;
- char* ret = abi::__cxa_demangle(&strName[iSymbolStart],
- strDemangledSymbol, &iDemangledSymbolSize, &iStatus);
- strDemangledSymbol = ret;
- if(iStatus == 0) {
- fprintf(fp," %s", strDemangledSymbol);
- } else {
- fprintf(fp," %s", "[Symbol Error]");
- }
- free(strDemangledSymbol);
- }
- if(iAddressStart != 0) {
- fprintf(fp," %s\n", &strName[iAddressStart]);
- } else {
- fprintf(fp,"[No Address Available]\n");
- }
- }
- free(strings);
- fprintf(fp,"\n");
- }
- pLocalNewStart = pLocalNewStart->pNext;
- }
- fclose(fp);
- //qDebug("End of printOutput(MemInfo *pLocalNewStart)");
- }
- bool findLeaks() {
- //qDebug("Start bool findLeaks()");
- MemInfo *pLocalNewStart = NULL;
- MemInfo *pLocalNewLast = NULL;
- DeletedMemInfo *pLocalDeletedStart = NULL;
- DeletedMemInfo *pLocalDeletedLast = NULL;
- //qDebug("Before making global variables NULL");
- pthread_mutex_lock (&mutexNew);
- pthread_mutex_lock(&mutexDelete);
- pLocalNewStart = pNewListStart;
- pLocalNewLast = pNewListLast;
- pLocalDeletedStart = pFreedListStart;
- pLocalDeletedLast = pFreedListLast;
- if(!pNewListStart) {
- pthread_mutex_unlock(&mutexDelete);
- pthread_mutex_unlock(&mutexNew);
- //qDebug("Returning from findLeaks()");
- return false;
- }
- pNewListStart = NULL;
- pNewListLast = NULL;
- pFreedListStart = NULL;
- pFreedListLast=NULL;
- pthread_mutex_unlock(&mutexDelete);
- pthread_mutex_unlock(&mutexNew);
- //qDebug("Before CreateVectorFromList");
- CreateVectorFromList(pLocalDeletedStart);
- //qDebug("Before GetAllLeaks");
- GetAllLeaks(pLocalNewStart);
- //qDebug("Before printOutput");
- printOutput(pLocalNewStart);
- //qDebug("Before Deleting all the memory");
- freeAllTheMemory(pLocalNewStart);
- free(pLocalNewStart);
- free(pLocalDeletedStart);
- //qDebug("At the end of FindLeaks()");
- return true;
- }
- void initLeakChecker() {
- pthread_mutex_init(&mutexNew, NULL);
- pthread_mutex_init(&mutexDelete, NULL);
- pNewListStart = (MemInfo*)malloc(sizeof(MemInfo));
- InitMemInfo(pNewListStart);
- pNewListLast = pNewListStart;
- pFreedListStart = (DeletedMemInfo*) malloc(sizeof(DeletedMemInfo));
- InitDeletedMemInfo(pFreedListStart);
- pFreedListLast = pFreedListStart;
- }
- LeakChecker::LeakChecker() {
- //INIT_//qDebug_FILE;
- initLeakChecker();
- }
- void LeakChecker::generateLeakReport() {
- //qDebug("Start generateLeakReport()");
- findLeaks();
- //qDebug("Stop generateLeakReport()");
- }
- LeakChecker::~LeakChecker() {
- //KILL_//qDebug_OBJECT;
- findLeaks();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement