Advertisement
Guest User

Untitled

a guest
Sep 26th, 2017
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.46 KB | None | 0 0
  1. #include "LeakChecker.h"
  2. #include "stdio.h"
  3. #include "stdlib.h"
  4. #include <pthread.h>
  5. #include <assert.h>
  6. #include <vector>
  7. #include <set>
  8. #include <list>
  9. #include <algorithm>
  10. #include <execinfo.h>
  11. #include <cxxabi.h>
  12.  
  13. //#include <QtCore/qDebug>
  14.  
  15. //#include "//qDebugTrace.h"
  16.  
  17. #define MAX_STACKSIZE 20
  18. #define MAX__SYMBOL_SIZE 200
  19. //#define LEAK_REPORT_FILE_NAME "/var/opt/bosch/dynamic/media/LOG/leak.log"
  20. #define LEAK_REPORT_FILE_NAME "/home/sunny/CodeTest/log/leak.log"
  21. //IMPLEMENT_//qDebug_OBJECT(LeakChecker,"LeakChecker.txt");
  22.  
  23. using namespace std;
  24.  
  25. struct MemInfo{
  26. int iSize;
  27. void* pAddress;
  28. void* stackTrace[MAX_STACKSIZE];
  29. int iStackSize;
  30. bool bIsLeak;
  31. bool bIsArray;
  32. bool bMarkDone;
  33. MemInfo* pNext;
  34. };
  35.  
  36. struct DeletedMemInfo{
  37. void *pAddress;
  38. bool bIsArray;
  39. DeletedMemInfo* pNext;
  40. };
  41.  
  42. pthread_mutex_t mutexNew;
  43. pthread_mutex_t mutexDelete;
  44. MemInfo *pNewListStart=NULL;
  45. MemInfo *pNewListLast=NULL;
  46. DeletedMemInfo *pFreedListStart = NULL;
  47. DeletedMemInfo *pFreedListLast=NULL;
  48. list<void*> arrFreed;
  49. set<void*> setUniqueAddressList;
  50. char** strings;
  51. unsigned int iFreeListSize = 0;
  52. unsigned int iTotalLeaksFound = 0;
  53. LeakChecker LeakChecker::m_globalLeakChecker;
  54.  
  55.  
  56. void InitDeletedMemInfo(DeletedMemInfo *pDeletedMemInfo) {
  57. pDeletedMemInfo->pAddress = NULL;
  58. pDeletedMemInfo->pNext = NULL;
  59. }
  60.  
  61. void InitMemInfo(MemInfo *pMemInfo) {
  62. pMemInfo->iSize = 0;
  63. pMemInfo->pAddress = 0;
  64. pMemInfo->iStackSize = 0;
  65. pMemInfo->pNext = 0;
  66. pMemInfo->bIsLeak = false;
  67. pMemInfo->bMarkDone = false;
  68. }
  69.  
  70. void* Allocate(int size, bool bIsArray) {
  71. void *p=malloc(size);
  72.  
  73. pthread_mutex_lock (&mutexNew);
  74.  
  75. if(pNewListStart) {
  76. MemInfo *pMemInfoNode = (MemInfo*) malloc(sizeof(MemInfo));
  77. InitMemInfo(pMemInfoNode);
  78.  
  79. pMemInfoNode->iStackSize = backtrace (pMemInfoNode->stackTrace, MAX_STACKSIZE);
  80. pMemInfoNode->pAddress = p;
  81. pMemInfoNode->iSize = size;
  82. pMemInfoNode->bIsArray = bIsArray;
  83.  
  84. pNewListLast->pNext = pMemInfoNode;
  85. pNewListLast = pMemInfoNode;
  86. }
  87.  
  88. pthread_mutex_unlock(&mutexNew);
  89.  
  90. return p;
  91. }
  92.  
  93. void Deallocate(void *p, bool bIsArray) {
  94. pthread_mutex_lock (&mutexDelete);
  95.  
  96. if(pFreedListLast) {
  97. DeletedMemInfo* pMemInfoNode = (DeletedMemInfo*) malloc( sizeof(DeletedMemInfo));
  98. InitDeletedMemInfo(pMemInfoNode);
  99. pMemInfoNode->pAddress = p;
  100. pMemInfoNode->bIsArray = bIsArray;
  101. pFreedListLast->pNext = pMemInfoNode;
  102. pFreedListLast=pMemInfoNode;
  103. iFreeListSize++;
  104. }
  105.  
  106. pthread_mutex_unlock(&mutexDelete);
  107. free(p);
  108. }
  109.  
  110. void* operator new (size_t size) {
  111. return Allocate(size, false);
  112. }
  113.  
  114. void* operator new[] (size_t size) {
  115. return Allocate(size, true);
  116. }
  117.  
  118. void operator delete[](void *p) {
  119. Deallocate(p, true);
  120. }
  121.  
  122.  
  123. void operator delete (void *p) {
  124. Deallocate(p, false);
  125. }
  126.  
  127.  
  128. void freeAllTheMemory(MemInfo *pLocalNewListStart) {
  129. MemInfo* pNode = pLocalNewListStart->pNext;
  130.  
  131. while(pNode) {
  132. MemInfo *pCurrent = pNode;
  133. pNode = pNode->pNext;
  134. free(pCurrent);
  135. }
  136. arrFreed.clear();
  137. }
  138.  
  139.  
  140.  
  141. void CreateVectorFromList(DeletedMemInfo* pLocalDeletedStart) {
  142. pLocalDeletedStart = pLocalDeletedStart->pNext;
  143.  
  144. while(pLocalDeletedStart) {
  145. arrFreed.push_back(pLocalDeletedStart->pAddress);
  146. DeletedMemInfo* pCurrentMemInfo = pLocalDeletedStart;
  147. pLocalDeletedStart = pLocalDeletedStart->pNext;
  148. free(pCurrentMemInfo);
  149. }
  150.  
  151. }
  152.  
  153. bool searchAndRemove(void *pAddress) {
  154. list<void*>::iterator it;
  155. for ( it=arrFreed.begin() ; it != arrFreed.end(); it++ ) {
  156. if(*it == pAddress) {
  157. arrFreed.erase(it);
  158. return true;
  159. }
  160. }
  161. return false;
  162. }
  163.  
  164. void GetAllLeaks(MemInfo *pLocalNewStart) {
  165. MemInfo* pNode = pLocalNewStart->pNext;
  166. //sort(arrFreed.begin(), arrFreed.end());
  167. int iCount = 0;
  168. while(pNode) {
  169. iCount++;
  170. if(!searchAndRemove(pNode->pAddress)) {
  171. pNode->bIsLeak = true;
  172. iTotalLeaksFound++;
  173. }
  174. pNode = pNode->pNext;
  175. }
  176. //qDebug("GetAllLeaks %d", iCount);
  177. }
  178.  
  179. void CreateUniqueLeakAddessVector(MemInfo* /*pLocalNewStart*/) {
  180. // pLocalNewStart = pLocalNewStart->pNext;
  181. // while(pLocalNewStart) {
  182. // if(pLocalNewStart->bIsLeak) {
  183. // for(int i=0; i < pLocalNewStart->iStackSize; i++ ) {
  184. // setUniqueAddressList.insert(pLocalNewStart->stackTrace[i]);
  185. // }
  186. // }
  187. // pLocalNewStart = pLocalNewStart->pNext;
  188. // }
  189.  
  190. }
  191.  
  192. void printfSymbolsWithAddresses(vector<void*> &arrSymbolAddress) {
  193. for(unsigned i=0; i<arrSymbolAddress.size(); i++) {
  194. printf("%p %s", arrSymbolAddress[i], strings[i]);
  195. }
  196. }
  197.  
  198. void GetSymbolNames() {
  199. // vector<void*> arrSymbolAddress;
  200. // for (set<void*>::iterator it=setUniqueAddressList.begin(); it!=setUniqueAddressList.end(); it++)
  201. // arrSymbolAddress.push_back(*it);
  202. // strings = backtrace_symbols(arrSymbolAddress.data(), arrSymbolAddress.size());
  203. // printfSymbolsWithAddresses(arrSymbolAddress);
  204. }
  205.  
  206. void getMangledSymbolName(char* strSymbolName, int *iSymbolStart , int *iSymbolLength,
  207. int *iAddressStart, int *iAddressLength) {
  208. *iSymbolStart = *iSymbolLength = *iAddressStart = *iAddressLength = 0;
  209.  
  210. for(int i=0; strSymbolName[i] != '\0'; i++) {
  211. if(strSymbolName[i] == '(') {
  212. strSymbolName[i] = NULL;
  213. *iSymbolStart = i+1;
  214. } else if( strSymbolName[i] == '+' ) {
  215. if(*iSymbolStart != 0) {
  216. *iSymbolLength = i - *iSymbolStart;
  217. strSymbolName[i] = NULL;
  218. continue;
  219. }
  220. } else if ( strSymbolName[i] == '[') {
  221. *iAddressStart = i;
  222. } else if(strSymbolName[i] == ']') {
  223. if(*iAddressStart != 0) {
  224. *iAddressLength = i - *iAddressStart;
  225. }
  226. }
  227.  
  228. }
  229. }
  230.  
  231. void printOutput(MemInfo *pLocalNewStart) {
  232.  
  233. //qDebug("Start void printOutput MemInfo *pLocalNewStart %d", iTotalLeaksFound);
  234. pLocalNewStart = pLocalNewStart->pNext;
  235. FILE *fp = fopen(LEAK_REPORT_FILE_NAME, "w");
  236. if(!fp) {
  237. //qDebug("unable to open file");
  238. return;
  239. } else {
  240. //qDebug("File Open Done");
  241. }
  242. int iCurrentCount = 0;
  243. while(pLocalNewStart) {
  244. if(pLocalNewStart->bIsLeak) {
  245. strings = backtrace_symbols(pLocalNewStart->stackTrace, pLocalNewStart->iStackSize);
  246. fprintf(fp,"Size = %d Pointer = %p %d outof %d \n", pLocalNewStart->iSize, pLocalNewStart->pAddress, iCurrentCount, iTotalLeaksFound);
  247. iCurrentCount++;
  248. //qDebug("Size = %d Pointer = %p %d outof %d \n", pLocalNewStart->iSize, pLocalNewStart->pAddress, iCurrentCount, iTotalLeaksFound);
  249. for(int i=2; i<pLocalNewStart->iStackSize; i++) {
  250. //printf("%s\n", strings[i]);
  251. //fflush(stdout);
  252. char * strName = strings[i];
  253. //fprintf(fp, "%s\n", strName);
  254. int iSymbolStart, iSymbolLength, iAddressStart, iAddressLength;
  255. getMangledSymbolName(strName, &iSymbolStart, &iSymbolLength,
  256. &iAddressStart, &iAddressLength);
  257. if(iSymbolStart != 0) {
  258. fprintf(fp,"%s", strName);
  259. }
  260. if(iSymbolLength == 0) {
  261. fprintf(fp," [No Symbol Availale]");
  262. } else {
  263. char *strDemangledSymbol = (char*) malloc(MAX__SYMBOL_SIZE);
  264. size_t iDemangledSymbolSize = MAX__SYMBOL_SIZE;
  265. int iStatus = 0;
  266. char* ret = abi::__cxa_demangle(&strName[iSymbolStart],
  267. strDemangledSymbol, &iDemangledSymbolSize, &iStatus);
  268. strDemangledSymbol = ret;
  269. if(iStatus == 0) {
  270. fprintf(fp," %s", strDemangledSymbol);
  271. } else {
  272. fprintf(fp," %s", "[Symbol Error]");
  273. }
  274. free(strDemangledSymbol);
  275. }
  276. if(iAddressStart != 0) {
  277. fprintf(fp," %s\n", &strName[iAddressStart]);
  278. } else {
  279. fprintf(fp,"[No Address Available]\n");
  280. }
  281. }
  282. free(strings);
  283. fprintf(fp,"\n");
  284. }
  285. pLocalNewStart = pLocalNewStart->pNext;
  286. }
  287. fclose(fp);
  288. //qDebug("End of printOutput(MemInfo *pLocalNewStart)");
  289. }
  290.  
  291. bool findLeaks() {
  292. //qDebug("Start bool findLeaks()");
  293.  
  294.  
  295. MemInfo *pLocalNewStart = NULL;
  296. MemInfo *pLocalNewLast = NULL;
  297. DeletedMemInfo *pLocalDeletedStart = NULL;
  298. DeletedMemInfo *pLocalDeletedLast = NULL;
  299.  
  300. //qDebug("Before making global variables NULL");
  301.  
  302. pthread_mutex_lock (&mutexNew);
  303. pthread_mutex_lock(&mutexDelete);
  304.  
  305. pLocalNewStart = pNewListStart;
  306. pLocalNewLast = pNewListLast;
  307. pLocalDeletedStart = pFreedListStart;
  308. pLocalDeletedLast = pFreedListLast;
  309.  
  310. if(!pNewListStart) {
  311. pthread_mutex_unlock(&mutexDelete);
  312. pthread_mutex_unlock(&mutexNew);
  313. //qDebug("Returning from findLeaks()");
  314. return false;
  315. }
  316.  
  317. pNewListStart = NULL;
  318. pNewListLast = NULL;
  319. pFreedListStart = NULL;
  320. pFreedListLast=NULL;
  321.  
  322. pthread_mutex_unlock(&mutexDelete);
  323. pthread_mutex_unlock(&mutexNew);
  324.  
  325. //qDebug("Before CreateVectorFromList");
  326. CreateVectorFromList(pLocalDeletedStart);
  327. //qDebug("Before GetAllLeaks");
  328. GetAllLeaks(pLocalNewStart);
  329. //qDebug("Before printOutput");
  330. printOutput(pLocalNewStart);
  331.  
  332. //qDebug("Before Deleting all the memory");
  333.  
  334. freeAllTheMemory(pLocalNewStart);
  335. free(pLocalNewStart);
  336. free(pLocalDeletedStart);
  337.  
  338.  
  339. //qDebug("At the end of FindLeaks()");
  340. return true;
  341. }
  342.  
  343. void initLeakChecker() {
  344. pthread_mutex_init(&mutexNew, NULL);
  345. pthread_mutex_init(&mutexDelete, NULL);
  346. pNewListStart = (MemInfo*)malloc(sizeof(MemInfo));
  347. InitMemInfo(pNewListStart);
  348. pNewListLast = pNewListStart;
  349.  
  350. pFreedListStart = (DeletedMemInfo*) malloc(sizeof(DeletedMemInfo));
  351. InitDeletedMemInfo(pFreedListStart);
  352. pFreedListLast = pFreedListStart;
  353.  
  354. }
  355.  
  356.  
  357. LeakChecker::LeakChecker() {
  358. //INIT_//qDebug_FILE;
  359. initLeakChecker();
  360. }
  361.  
  362. void LeakChecker::generateLeakReport() {
  363. //qDebug("Start generateLeakReport()");
  364. findLeaks();
  365. //qDebug("Stop generateLeakReport()");
  366. }
  367.  
  368. LeakChecker::~LeakChecker() {
  369. //KILL_//qDebug_OBJECT;
  370. findLeaks();
  371. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement