[c++]记录Windows程序“应用程序错误”到异常日志

news/2024/6/17 21:46:14

客户反应,程序在运行中经常发生“非法操作”的错误,0x00XXXXXX的内存不能为读之类的错误。

这断代码的作用就是 将这些 异常 保存到日志文件, 对照MAP文件可以找到源代码的出错行。

#include "Shlwapi.h"
#pragma comment( lib,"Shlwapi.lib")

 
#include
std::vector g_vErrCode;

CString GetNow()
{
 CHAR szData[MAX_PATH] = {'/0'};
 CHAR szTime[MAX_PATH] = {'/0'};
 _strdate( szData );
 _strtime( szTime );

 CString strRet;
 strRet.Format( "£¨%s£©%s", szData, szTime);
 strRet.Replace( "/", "_");
 strRet.Replace( ":", "£º");
 return strRet;
}


CString GetAppPath()
{
 TCHAR tszBuf[MAX_PATH] = {'/0'};
 GetModuleFileName( NULL, tszBuf, MAX_PATH);

 CString strDir, tmpDir;
 tmpDir = tszBuf;
 strDir = tmpDir.Left( tmpDir.ReverseFind('//') );

 return strDir;
}


#define EXE_NAME "XVODNew.exe"

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
  CString strPath;
 strPath.Format( "%s//%s", GetAppPath(), EXE_NAME);

 if( !PathFileExists(strPath) )
 {
  MessageBox( NULL, "Ç뽫µ÷ÊÔ³ÌÐò·ÅÔÚ±»µ÷ÊÔ³ÌÐòͬһĿ¼Ï£¡", NULL, MB_OK );
  return -1;
 }


 STARTUPINFO si = {'/0'};
 si.cb = sizeof(si);
 si.dwFlags = STARTF_USESHOWWINDOW;
 si.wShowWindow = SW_SHOW;
    PROCESS_INFORMATION pi = {'/0'};
 
 if( !CreateProcess( (LPSTR)(LPCSTR)strPath
  , NULL
  , NULL           
        , NULL           
        , FALSE          
        , DEBUG_PROCESS//CREATE_SUSPENDED
        , NULL           
        , GetAppPath()   
        , &si            
        , &pi   
  ) )
    {
  MessageBox( NULL, "Æô¶¯½ø³Ìʧ°Ü!", NULL, MB_OK );
  return -2;
    }
/* 
 if( !DebugActiveProcess(pi.dwProcessId) )
 {
  MessageBox( NULL, "µ÷ÊÔ½ø³Ìʧ°Ü", NULL, MB_OK );
  return -3;
 }

 if( ::ResumeThread( pi.hThread ) == (DWORD)-1 )
 {
  MessageBox( NULL, "¼¤»î½ø³Ìʧ°Ü", NULL, MB_OK );
  return -4;
 }
 */


 CString strDir;
 strDir.Format( "%s//Log"
  , GetAppPath()
  );
 CreateDirectory( strDir, NULL); 
 
 CString strLog;
 strLog.Format( "%s//Log//%s.log"
  , GetAppPath()
  , GetNow()
  );
 
 CFile file;
 if( file.Open( strLog
  , CFile::modeCreate | CFile::modeReadWrite
  , NULL
  ) == 0 )
 {
  MessageBox( NULL, "´´½¨ÈÕÖ¾Îļþʧ°Ü", NULL, MB_OK );
  return -4;
 }

 DEBUG_EVENT de;
 BOOL bContinue = TRUE;
 DWORD dwContinueStatus = 0;
 
 while( bContinue )
 {
  bContinue = WaitForDebugEvent( &de, INFINITE);
  
  switch( de.dwDebugEventCode )
  {
  case EXCEPTION_DEBUG_EVENT:
   {
    EXCEPTION_DEBUG_INFO info = de.u.Exception;
    BOOL bExist = FALSE;

    // ÊÇ·ñÊǵÚÒ»´Î³ö´í
    std::vector ::iterator iter;
    for( iter = g_vErrCode.begin(); iter != g_vErrCode.end(); iter++)
    {
     if( (LPVOID)(*iter) == info.ExceptionRecord.ExceptionAddress )
     {
      bExist = TRUE;
      break;
     }
    }

    if( !bExist )
    {
     g_vErrCode.push_back(info.ExceptionRecord.ExceptionAddress);
     
     CString strMsg;
     strMsg.Format( "%s/r/n"
      "/t/t/t/tFirstChance:%d/t/r/n"
      "/t/t/t/tExceptionCode:0x%X/r/n"
      "/t/t/t/tExceptionFlags:%d/r/n"
      "/t/t/t/tExceptionAddress:0x%X/r/n"
      "/t/t/t/tNumberParameters:%d/r/n"
      "/t/t/t/tIsWrite:%d/r/n"
      "/t/t/t/tAccessAddress:0x%X/r/n"
      "/r/n"
      , GetNow()
      , info.dwFirstChance
      , info.ExceptionRecord.ExceptionCode
      , info.ExceptionRecord.ExceptionFlags
      , info.ExceptionRecord.ExceptionAddress
      , info.ExceptionRecord.NumberParameters
      , info.ExceptionRecord.ExceptionInformation[0]
      , info.ExceptionRecord.ExceptionInformation[1]
      );
     file.Write( strMsg.GetBuffer(0), strMsg.GetLength());
     strMsg.ReleaseBuffer();
     file.Flush();
    }
    else
    {
     if( MessageBox( NULL, "µÚ¶þ´ÎÔÚÏàͬλÖóö´í£¡,ÊÇ·ñÍ˳ö?", NULL, MB_YESNO) == IDYES )
     {
      bContinue = FALSE;
      break;
     }
    }

    dwContinueStatus = DBG_CONTINUE;
    break;
   }

   
  case EXIT_PROCESS_DEBUG_EVENT:
   {
    bContinue = FALSE;
    break;
   }
   
  default:
   {
    dwContinueStatus = DBG_CONTINUE;
    break;
   }
  }
  
  ContinueDebugEvent(de.dwProcessId, de.dwThreadId, dwContinueStatus);
 }

 file.Flush();
 file.Close();


 return 0;
}





http://www.niftyadmin.cn/n/3654646.html

相关文章

VMware GSX Server 3.2.1官方下载地址

VMware官方下载:For Windows 版系统:http://download3.vmware.com/software/gsx/VMware-gsx-server-installer-3.2.1-19281.exe For Linux 版系统 Tar包:http://download3.vmware.com/software/gsx/VMware-gsx-3.2.1-19281.tar.gz For Linu…

[c++]一个对MSXML的封装类 使用C++的Smart Pointer 对MSXML DOM封装,可以方便地访问xml文件

#pragma once#include "XmlNode.h"//-------------------------------------------------------------------------// Classes Name :CXml CXmlNode CXmlNodes// Author :王嘉 QQ32775973 sky-sea-earth21cn.com// CreateTime :2005-10-23// Memo …

需求文档是否包含业务实体分析?

【主要观点来自经典书籍:软件需求最佳实践---SERU过程框架与应用】 最近在做软件需求规格说明书模板规划,其中涉及一个主题是否报业务实体分析,大多数人对于这个基本处于不知的状态,有人不知道干吗用,有人不知道图例&a…

[C#] 自己封装的一个数据库访问类 让ado.net 用起来和ado一样

using System;using System.Data;using System.Collections;using System.Data.OleDb;using System.Data.SqlClient;namespace Government.Common{ /// /// CDataBase 的摘要说明。 /// public class CDataBase{public CDataBase(){}/// /// 取单值 /// /// SQL 命令/// 结果p…

Axure RP6学习笔记(1)

无意中得知交互原型设计工具Axure RP,觉得对目前的工作可能会有很大的助力,从网上搜索了很多资料,发现大部分都是基于5.X或4.X版本的文档,但是也给了我很多的启示,非常感谢网友们的无私奉献, 从今天开始写上…

[C#] 生成略缩图

// 生成略缩图 string strImage null; string strRegex ".*?)(""|)?(/s|>)";MatchCollection mc Regex.Matches( FreeTextBox.Text, strRegex,RegexOptions.IgnoreCase | RegexOptions.Singleline);foreach(Match m in mc){strImage m.Groups…

Axure RP6 学习笔记(2)

学习资料【Axure 快速原型设计Axure Rapid Prototyping 作者:陈良泳】 以学习的习惯,先来一个例子~~~ 第一个实例 简单登陆界面 案例描述 这是一个较为简单的登陆界面,输入用户名、密码后,点击登陆按钮进行登陆校验:…

央行发布第三方支付业务系统检测认证新规

中国人民银行2011年6月21日发布《非金融机构支付服务业务系统检测认证管理规定》,明确将对因认证问题造成不良后果的机构给予处罚,保障非金融机构支付服务业务系统检测认证工作规范有序开展,并即日起开始施行。金融机构支付服务业务系统检测认…