示例#1
0
void	PrintCallStackOfThisThread(const wchar_t* name, const wchar_t* expression, const wchar_t* function, const wchar_t* file, int line)
{
	if (name == NULL) name = L"Unknown";
	if (expression == NULL) expression = L"No Expression";
	if (function == NULL) function = L"Unknown Function";
	if (file == NULL) file = L"Unknown File";

	wchar_t folder[MAX_PATH] = { 0, };
	GetProcessFolder(::GetCurrentProcess(), folder, _countof(folder));

	wchar_t callStackFile[MAX_PATH] = { 0, };

	SYSTEMTIME systemTime;
	::memset(&systemTime, 0, sizeof(systemTime));
	::GetLocalTime(&systemTime);

	::swprintf_s(callStackFile, _countof(callStackFile), L"%s/%s_%04d-%02d-%02d.rpt",
		folder, name, systemTime.wYear, systemTime.wMonth, systemTime.wDay);

	TextFile textFile;

	int count = 0;
	while (textFile.open(callStackFile, GENERIC_WRITE, FILE_SHARE_READ) == false &&
		textFile.create(callStackFile, GENERIC_WRITE, FILE_SHARE_READ) == false)
	{
		++count;

		::swprintf_s(callStackFile, _countof(callStackFile), L"%s/%s_%04d-%02d-%02d(%d).rpt",
			folder, name, systemTime.wYear, systemTime.wMonth, systemTime.wDay, count);
	}

	textFile.seek(0, FILE_END);

	DumpPrint(&textFile, L"[%04d-%02d-%02d %02d:%02d:%02d] %s at %s\r\n%s(%d)\r\n",
		systemTime.wYear, systemTime.wMonth, systemTime.wDay,
		systemTime.wHour, systemTime.wMinute, systemTime.wSecond,
		expression,
		function,
		file,
		line);

	// current thread call stack
	DWORD processId = ::GetCurrentProcessId();
	HANDLE process = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId);
	if (process != NULL)
	{
		HANDLE thread = ::GetCurrentThread();
		DWORD threadId = ::GetCurrentThreadId();

		DumpPrint(&textFile, L"%s(Thread(%u) Call Stack)\r\n", function, threadId);

		EXCEPTION_RECORD exceptionRecord = {};
		CONTEXT context = {};
		EXCEPTION_POINTERS exceptionPointers = { &exceptionRecord, &context };

		context.ContextFlags = CONTEXT_FULL;
		if (::GetThreadContext(thread, &context) != FALSE)
		{
			PrintThreadCallStack(&textFile, &exceptionPointers, process, thread);

			DumpPrint(&textFile, L"\r\n");
		}

		::CloseHandle(process);
		process = NULL;
	}

	DumpPrint(&textFile, L"\r\n");

	textFile.flush();
}