手写Visual C++软件内存泄漏检测代码

不废话,直接撸代码

#include 
#include 
#pragma intrinsic(_ReturnAddress)

namespace foundation
{
	struct FunctionCall
	{
		std::string FunctionName;
		std::string FileName;
		int	LineNumber;
	};


	static std::map _memAddrMap;
	static std::mutex _memAddrMutex;

	void MemleakNewDump2(const void* block, const void* pRetAddr)
	{
		_memAddrMutex.lock();
		_memAddrMap[block] = pRetAddr;
		_memAddrMutex.unlock();
	}

	void memLeakFree2(const void* db)
	{
		_memAddrMutex.lock();
		_memAddrMap.erase(db);
		_memAddrMutex.unlock();
	}

	void dumpMemLeak2()
	{
		_memAddrMutex.lock();

		SYSTEMTIME st;
		GetLocalTime(&st);
		char sz[MAX_PATH + 4];
		sprintf(sz, "memLeak-%d-%02d-%02d=%02d-%02d-%02d.txt", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
		FILE* f = fopen(sz, "w");
		if (!f)
		{
			_memAddrMutex.unlock();
			return;
		}

		int cnt = 0;
		char _sz[256];

		// Walk through the stack frames.
		HANDLE hProcess = GetCurrentProcess();
		HANDLE hThread = GetCurrentThread();
		if (!SymInitialize(hProcess, NULL, TRUE))
		{
			SymCleanup(hProcess);
			_memAddrMutex.unlock();
			fclose(f);
			return;
		}

		// 1. Get function name at the address
		const int nBuffSize = (sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64);
		ULONG64 symbolBuffer[nBuffSize];
		PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)symbolBuffer;

		pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
		pSymbol->MaxNameLen = MAX_SYM_NAME;

		for (auto it : _memAddrMap)
		{
			FunctionCall curCall;
			curCall.FunctionName = "";
			curCall.FileName = "";
			curCall.LineNumber = 0;

			DWORD64 dwSymDisplacement = 0;
			if (SymFromAddr(hProcess, (DWORD64)(it.second), &dwSymDisplacement, pSymbol))
			{
				curCall.FunctionName = pSymbol->Name;
			}

			//2. get line and file name at the address
			IMAGEHLP_LINE64 lineInfo = { sizeof(IMAGEHLP_LINE64) };
			DWORD dwLineDisplacement = 0;

			if (SymGetLineFromAddr64(hProcess, (DWORD64)(it.second), &dwLineDisplacement, &lineInfo))
			{
				curCall.FileName = (lineInfo.FileName);
				curCall.LineNumber = lineInfo.LineNumber;
			}

			cnt++;
			fprintf(f, "\n%d\n", cnt);
			fprintf(f, "FileName: %s\n", curCall.FileName.c_str());
			fprintf(f, "FunctionName: %s\n", curCall.FunctionName.c_str());
			fprintf(f, "LineNumber: %d\n", curCall.LineNumber);
			fprintf(f, "======================================\n\n");
		}

		SymCleanup(hProcess);
		fclose(f);

		_memAddrMutex.unlock();
	}
};



int main(int argc, char* argv[])
{
	int ret = 0;
    int* p =  new int;

	foundation::dumpMemLeak2();//<--
	return ret;
}

#define GUI_MEMLEAK_DETECT
void* __cdecl operator new(size_t const size)
{
	for (;;)
	{
		if (void* const block = malloc(size))
		{
#ifdef GUI_MEMLEAK_DETECT
			const void* p = _ReturnAddress();
			foundation::MemleakNewDump2(block, p);//<--
#endif
			return block;
		}

		if (_callnewh(size) == 0)
		{
			if (size == SIZE_MAX)
			{
				throw std::exception("bad alloc, SIZE_MAX");
			}
			else
			{
				throw std::exception("bad alloc");
			}
		}
	}
}

void __cdecl operator delete(void* p)
{
#if !defined(_ATL_NO_DEBUG_CRT) && defined(_DEBUG)
	_free_dbg(p, _NORMAL_BLOCK);
#else
	free(p);
#endif 

#ifdef GUI_MEMLEAK_DETECT
	foundation::memLeakFree2(p); //<--
#endif
}

你可能感兴趣的:(C++,Windows,c++,算法,开发语言)