std::basic_string<TCHAR> CallStack::toString() { TCHAR symInfo[MLD_MAX_NAME_LENGTH]; TCHAR srcInfo[MLD_MAX_NAME_LENGTH]; int totalSize = 0; CallStackFrameEntry* p = 0; // Make sure initSymbols() has been called. assert(m_pSymbol); std::basic_string<TCHAR> stackTrace; p = &traceinfo[0]; while(p[0].addrPC.Offset) { symFunctionInfoFromAddresses(p[0].addrPC.Offset, p[0].addrFrame.Offset, symInfo, MLD_MAX_NAME_LENGTH); symSourceInfoFromAddress(p[0].addrPC.Offset, srcInfo, MLD_MAX_NAME_LENGTH); TCHAR buffer[3*MLD_MAX_NAME_LENGTH] = {0}; _stprintf(buffer, _T("%s->%s()\n"), srcInfo, symInfo); stackTrace += buffer; p++; } return stackTrace; }
void CMemLeakDetect::dumpMemoryTrace() { POSITION pos; LPVOID addr; AllocBlockInfo ainfo; TCHAR buf[MLD_MAX_NAME_LENGTH]; TCHAR fileName[MLD_MAX_NAME_LENGTH]; TCHAR symInfo[MLD_MAX_NAME_LENGTH]; TCHAR srcInfo[MLD_MAX_NAME_LENGTH]; size_t totalSize = 0; int numLeaks = 0; STACKFRAMEENTRY* p = 0; ofstream myfile; #ifdef UNICODE char dest[1024] ; #endif struct tm timeinfo; __time64_t long_time; _time64(&long_time); // Convert to local time. _localtime64_s(&timeinfo, &long_time); TCHAR TempDir[MAX_PATH]; TCHAR ProcName[MAX_PATH]; GetTempPath(MAX_PATH, TempDir); ProcName[0] = _T('\0'); GetModuleBaseName(GetCurrentProcess(), NULL, ProcName, sizeof(ProcName)/sizeof(TCHAR)); _stprintf_s(fileName, MLD_MAX_NAME_LENGTH, _T("%smldetector-(%s)_"), TempDir, ProcName); _tcsftime(buf,MLD_MAX_NAME_LENGTH, _T("%b%d-%Y__%H-%M-%S.log"),&timeinfo); _tcscat_s(fileName,MLD_MAX_NAME_LENGTH, buf); myfile.open (fileName); DeleteOldTempFiles(TempDir, _T("mldetector-(*.log"), 7); // _tcscpy_s(symInfo, MLD_MAX_NAME_LENGTH, MLD_TRACEINFO_NOSYMBOL); _tcscpy_s(srcInfo, MLD_MAX_NAME_LENGTH, MLD_TRACEINFO_NOSYMBOL); // pos = m_AllocatedMemoryList.GetStartPosition(); // while(pos != m_AllocatedMemoryList.end()) { numLeaks++; _stprintf_s(buf, MLD_MAX_NAME_LENGTH, _T("Memory Leak(%d)------------------->\n"), numLeaks); AfxTrace(buf); #ifdef UNICODE WideCharToMultiByte( CP_ACP, 0, buf, -1, dest, 1024, NULL, NULL ); myfile << dest; #else myfile << buf; #endif // m_AllocatedMemoryList.GetNextAssoc(pos, (LPVOID &) addr, (AllocBlockInfo&) ainfo); if (ainfo.fileName[0] != NULL) { _stprintf_s(buf, MLD_MAX_NAME_LENGTH, _T("Memory Leak <0x%p> bytes(%d) occurance(%d) %s(%d)\n"), ainfo.address, ainfo.size, ainfo.occurance, ainfo.fileName, ainfo.lineNumber); } else { _stprintf_s(buf, MLD_MAX_NAME_LENGTH, _T("Memory Leak <0x%p> bytes(%d) occurance(%d)\n"), ainfo.address, ainfo.size, ainfo.occurance); } // AfxTrace(buf); #ifdef UNICODE WideCharToMultiByte( CP_ACP, 0, buf, -1, dest, 1024, NULL, NULL ); myfile << dest; #else myfile << buf; #endif // p = &ainfo.traceinfo[0]; while(p[0].addrPC.Offset) { symFunctionInfoFromAddresses( p[0].addrPC.Offset, p[0].addrFrame.Offset, symInfo, MLD_MAX_NAME_LENGTH); symSourceInfoFromAddress( p[0].addrPC.Offset, srcInfo ); _stprintf_s(buf, MLD_MAX_NAME_LENGTH, _T("%s->%s()\n"), srcInfo, symInfo); AfxTrace(_T("%s->%s()\n"), srcInfo, symInfo); #ifdef UNICODE WideCharToMultiByte( CP_ACP, 0, buf, -1, dest, 1024, NULL, NULL ); myfile << dest; #else myfile << buf; #endif p++; } totalSize += ainfo.size; } _stprintf_s(buf, MLD_MAX_NAME_LENGTH, _T("\n-----------------------------------------------------------\n")); AfxTrace(buf); #ifdef UNICODE WideCharToMultiByte( CP_ACP, 0, buf, -1, dest, 1024, NULL, NULL ); myfile << dest; #else myfile << buf; #endif if(!totalSize) { _stprintf_s(buf, MLD_MAX_NAME_LENGTH, _T("No Memory Leaks Detected for %d Allocations\n\n"), memoccurance); AfxTrace(buf); #ifdef UNICODE WideCharToMultiByte( CP_ACP, 0, buf, -1, dest, 1024, NULL, NULL ); myfile << dest; #else myfile << buf; #endif } else { _stprintf_s(buf, MLD_MAX_NAME_LENGTH, _T("Total %d Memory Leaks: %d bytes Total Alocations %d\n\n"), numLeaks, totalSize, memoccurance); } AfxTrace(buf); #ifdef UNICODE WideCharToMultiByte( CP_ACP, 0, buf, -1, dest, 1024, NULL, NULL ); const TCHAR *umb = _T("Unicode"); myfile << dest; #else myfile << buf; const TCHAR *umb = _T("Multibyte"); #endif #ifdef _WIN64 const TCHAR *w64 = _T("64 bit"); #else const TCHAR *w64 = _T("32 bit"); #endif #ifdef NDEBUG const TCHAR *dbg = _T("release build."); #else const TCHAR *dbg = _T("debug build."); #endif _stprintf_s(TempDir, MAX_PATH, _T("%s %s %s\n"), umb, w64, dbg); #ifdef UNICODE WideCharToMultiByte( CP_ACP, 0, TempDir, -1, dest, 1024, NULL, NULL ); myfile << dest; AfxTrace(TempDir); #else myfile << TempDir; AfxTrace(TempDir); #endif myfile.close(); }