使用log分析和记录

       适用于无法对code Debug。函数间的调用执行关系只能通过查看源代码,无法确定运行的程序是否走到相应的函数。利用C++的RAII机制,进入函数和离开函数自动记录一次Log,输出文件查看程序执行流程。

part code:

#define LOG_FUNCTION(filename, funcname, lines)  \
    CLogFunction logFunctionName(filename, funcname, lines)
	
#define MAX_STR_LEN 1024
void __stdcall write_log(char* lpszFmt, ...)
{
	FILE* f = fopen("shell.log", "at");	
	if(f)
	{
	     va_list args;
	     va_start(args, lpszFmt);
	     char cBuffer[MAX_STR_LEN];
	     memset(cBuffer,0,MAX_STR_LEN);
	     _vsnprintf( cBuffer, MAX_STR_LEN-1, lpszFmt, args);
	     fwrite(cBuffer,strlen(cBuffer),1,f);
	     fclose(f);
	}
}

class CLogFunction
{
public:
	CLogFunction(char *szFileName, char *szFunctionName, UINT32 uLine)
	{
    LOG_FUNCTION(__FILE__, __FUNCTION__, __LINE__);

		m_pFileName = szFileName;
		m_pFunctionName = szFunctionName;
		m_nid = InterlockedIncrement(&nID);
		write_log(  "ThreadID:%d +[S:%d]EnterFunc:%s +Line:%d", 
			GetCurrentThreadId(), 
			m_pFunctionName,
			uLine);
	}
	~CLogFunction()
	{
    LOG_FUNCTION(__FILE__, __FUNCTION__, __LINE__);

		write_log(  "ThreadID:%d +[E:%d]LeaveFunc:%s ", 
			GetCurrentThreadId(), 
			m_pFunctionName);
	}
private:
	char *m_pFileName;
	char *m_pFunctionName;
	long m_nid;
};


然后在每个函数的入口添加代码,如:

 

int main(int argc, char *argv[])
{
	LOG_FUNCTION(__FILE__, __FUNCTION__, __LINE__);


 

简单记录部分Function,具体实现用到多线程,自动为工程中函数添加LOG_FUNCTION()以及对生成log文件的分析工具。。。。。




***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
简单log记录输出:

// stdafx.cpp : 只包括标准包含文件的源文件
// SuiteCommand.pch 将作为预编译头
// stdafx.obj 将包含预编译类型信息

#include "stdafx.h"

CFile g_hFile;
BOOL is_open = FALSE;
void DLL_LOG_W(__in LPCWSTR lpOutputString)
{
	OutputDebugStringW(lpOutputString);
}

void DLL_LOG_A(__in LPCSTR lpOutputString)
{
	OutputDebugStringA(lpOutputString);
}

HINSTANCE GetCurDllInstance()
{
	HINSTANCE hInstance = NULL;
	MEMORY_BASIC_INFORMATION mbi = {0};
	do 
	{
		if (0 == VirtualQuery((void*)(&GetCurDllInstance), &mbi, sizeof(mbi)))
		{
			break;
		}
		//BaseAddress具体某页的基指,而AllocationBase则是连续N页的基指,AllocationBase就是instance
		hInstance = reinterpret_cast<HINSTANCE>(mbi.AllocationBase);
	} while (FALSE);

	ASSERT(NULL != hInstance);
	return hInstance;
}

CString GetCurDllDir()
{
	TCHAR szFileName[1024] = {0};
	CString strDir;

	if (0 != GetModuleFileName(GetCurDllInstance(), szFileName, _countof(szFileName)))
	{
		strDir = szFileName;
		int nIndex = strDir.ReverseFind(_T('\\'));
		strDir = strDir.Left(nIndex);
	}
	ASSERT(!strDir.IsEmpty());

	return strDir;
}

void initlog()
{
	CString path = GetCurDllDir();
	CString timestr;
	CreateDirectory(path + _T("\\log"),NULL);
	path +=_T("\\log\\debug.log");
	is_open = g_hFile.Open(path, CFile::modeCreate | CFile::modeWrite|CFile::modeNoTruncate | CFile::shareDenyWrite);
	if (is_open == FALSE)
	{
			path = GetCurDllDir();
			path +=_T("\\debug.log");
			is_open = g_hFile.Open(path, CFile::modeCreate | CFile::modeWrite|CFile::modeNoTruncate | CFile::shareDenyWrite);
			return;
	}

	ULONGLONG len = g_hFile.GetLength();
	if (len>(1024*1024))
	{
		g_hFile.Close();
		g_hFile.Remove(path);
		g_hFile.Open(path, CFile::modeCreate | CFile::modeWrite|CFile::modeNoTruncate | CFile::shareDenyWrite);

	}

}
void closelog()

{
	if (is_open)
	{
		g_hFile.Close();
		is_open = FALSE;
	}
}

void logoutput(CStringA logs)
{
	if (is_open)
	{
	/*	CTime tm;
		tm=CTime::GetCurrentTime(); */

		SYSTEMTIME st;
		CStringA strDate,strTime;
		GetLocalTime(&st);
		strDate.Format("%04d/%02d/%02d",st.wYear,st.wMonth,st.wDay);
		strTime.Format("%02d:%02d:%02d",st.wHour,st.wMinute,st.wSecond);
		g_hFile.SeekToEnd();
		CStringA temp = "LOGOUT ";
		g_hFile.Write(temp,temp.GetLength());
		g_hFile.Write(strDate,strDate.GetLength());
		g_hFile.Write("--",2);
		g_hFile.Write(strTime,strTime.GetLength());
		g_hFile.Write(":",1);
		g_hFile.Write(logs,logs.GetLength());
		g_hFile.Write("\r\n",(UINT)strlen("\r\n"));
	}

}
BOOL CheckisUnicode(WCHAR* str)
{
	int len = wcslen(str);
	WCHAR* ptr = str;

	for(int i = 0;i<len;i++)
	{
		WCHAR code = ptr[i];
		code = code&0xFF00;
		if (code)
		{
			return TRUE;
		}
	}
	return FALSE;
}


// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件

#pragma once

void DLL_LOG_W(__in LPCWSTR lpOutputString);

void DLL_LOG_A(__in LPCSTR lpOutputString);

void logoutput(CStringA logs);
void initlog();
void closelog();
BOOL CheckisUnicode(WCHAR* str);



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值