1、MiniDump文件的创建:

创建miniDump的方法有很多。可以通过MiniDumpCreateDumpWin32Api创建。必要参数为EXCEPTION_POINTERS结构,获取这个结构可以通过在异常出通过GetExceptionInfomation函数API获取这个结构,也可以通过SetUnhandleExceptionFilter函数设置自定义异常处理函数(注意:这个函数是处理系统无法处理的异常时触发的),这个自定义异常处理函数的函数原型为
typedef LONG (WINAPI *PTOP_LEVEL_EXCEPTION_FILTER)(_In_ struct _EXCEPTION_POINTERS *ExceptionInfo);

这个里面的参数为系统传入的,其中包括了异常信息,以及上下文句柄。
而写Dump的函数原型为:

BOOL MiniDumpWriteDump( HANDLE hProcess, DWORD ProcessId, HANDLE hFile, MINIDUMP_TYPE DumpType, PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, PMINIDUMP_CALLBACK_INFORMATION CallbackParam );

其中需要主要的是第三个参数和 第四个参数:第三个参数表示需要在dump文件中记录什么信息。详细解释见MSDN,第四个参数从众多网上例子来看很多都没有在意这个参数。这个参数的结构体原型如下:

typedef struct _MINIDUMP_EXCEPTION_INFORMATION {
    DWORD ThreadId;
    PEXCEPTION_POINTERS ExceptionPointers;
    BOOL ClientPointers;
} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION;

ClientPointers指针这个参数到底什么时候为TRUE什么时候为FALSE呢?
MSDN的解释为如果调试进程在内存中为true,否则为false,如果错误地址所在进程在内存中,应该为false,否则为true,总结一句话为,如果要记录内存中的地址相关信息(包括堆栈,偏移地址,断片地址,节表信息等等)应该为FALSE,其他为true。这个参数决定着dump文件的价值。

分析堆栈信息

堆栈信息可以帮助我们快速定位程序所谓位置以及错误发生的原因。有利于程序的错误修复,加快工作效率。如果获取异常程序的堆栈信息呢?
    在设置自定义异常处理函数时,传入的异常信息结构中包括了一个CONTEXT结构体的指针。这个指针就是上下文句柄。

这个结构体的原型如下:

typedef struct _CONTEXT {

RD ContextFlags;

DWORD   Dr0;
    DWORD   Dr1;
    DWORD   Dr2;
    DWORD   Dr3;
    DWORD   Dr6;
    DWORD   Dr7;

FLOATING_SAVE_AREA FloatSave;

DWORD   SegGs;
    DWORD   SegFs;
    DWORD   SegEs;
    DWORD   SegDs;

DWORD   Edi;
    DWORD   Esi;
    DWORD   Ebx;
    DWORD   Edx;
    DWORD   Ecx;
    DWORD   Eax;

DWORD   Ebp;
    DWORD   Eip;
    DWORD   SegCs;              // MUST BE SANITIZED
    DWORD   EFlags;             // MUST BE SANITIZED
    DWORD   Esp;
    DWORD   SegSs;

BYTE    ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];

} CONTEXT;

这个结构体的详细解释见MSDN。

通过这个结构我们里面的相关信息就可以获取异常程序的堆栈信息。获取堆栈信息的API 函数原型如下:

BOOL IMAGEAPI StackWalk64( DWORD MachineType, HANDLE hProcess, HANDLE hThread, LPSTACKFRAME64 StackFrame, PVOID ContextRecord, PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress );

第一个参数:表示本机芯片类型,芯片不同也表明取值不一样。

第四个参数表示获取堆栈信息所需要的一些关键信息。

其他参数详情见MSDN。

举例如下:这个例子网上很多,详细信息请将CONTEXT结构和STACKFRAME64结构结合学习。

unsigned long dwImageType=IMAGE_FILE_MACHINE_I386;//设置默认芯片类型为X86

#ifdef _M_IX86
    sf.AddrPC.Offset = c.Eip;//当芯片类型为X86是,程序计数器地址的偏移量(或者首地址)取值为CONTEXT结构的Eip成员
    sf.AddrPC.Mode = AddrModeFlat;//平面寻址//详细解释见MSDN
    sf.AddrStack.Offset = c.Esp;//堆栈偏移
    sf.AddrStack.Mode = AddrModeFlat;
    sf.AddrFrame.Offset = c.Ebp;//帧偏移
    sf.AddrFrame.Mode = AddrModeFlat;
#elif _M_X64
    dwImageType = IMAGE_FILE_MACHINE_AMD64;
    sf.AddrPC.Offset = c.Rip;
    sf.AddrPC.Mode = AddrModeFlat;
    sf.AddrFrame.Offset = c.Rbp;
    sf.AddrFrame.Mode = AddrModeFlat;
    sf.AddrStack.Offset = c.Rsp;
    sf.AddrStack.Mode = AddrModeFlat;
#elif _M_IA64
    dwImageType = IMAGE_FILE_MACHINE_IA64;
    sf.AddrPC.Offset = c.StIIP;
    sf.AddrPC.Mode = AddrModeFlat;
    sf.AddrFrame.Offset = c.IntSp;
    sf.AddrFrame.Mode = AddrModeFlat;
    sf.AddrBStore.Offset = c.RsBSP;
    sf.AddrBStore.Mode = AddrModeFlat;
    sf.AddrStack.Offset = c.IntSp;
    sf.AddrStack.Mode = AddrModeFlat;

#endif

获取错误函数API

SymGetSymFromAddr64(

_In_ HANDLE hProcess,

_In_ DWORD64 qwAddr,

_Out_opt_ PDWORD64 pdwDisplacement,

_Inout_ PIMAGEHLP_SYMBOL64 Symbol

);

获取错误错误行的API

BOOL
IMAGEAPI
SymGetLineFromAddr64(
    _In_ HANDLE hProcess,
    _In_ DWORD64 qwAddr,
    _Out_ PDWORD pdwDisplacement,
    _Out_ PIMAGEHLP_LINE64 Line64
    );

//获取错误模块

BOOL
IMAGEAPI
SymGetModuleInfo64(
    _In_ HANDLE hProcess,
    _In_ DWORD64 qwAddr,
    _Out_ PIMAGEHLP_MODULE64 ModuleInfo
    );

这三个API的参数详细解释见MSDN,

第二个参数的取值为为当前程序的程序计时器偏移地址,表示从当前程序的主线程开始获取错误信息。

符号表:

symbolTable是分析dump文件的关键所在,symbol可以帮助更加准确的定位程序错误。因此,在获取堆栈信息获取生成dump文件之前绑定符号表是必须的。绑定的符号表的API如下:

BOOL IMAGEAPI SymInitialize( HANDLE hProcess, PCSTR UserSearchPath, BOOL fInvadeProcess );

详细解释见MSDN,这里详细讲解第二个参数,符号表路径,如何设置符号表路径呢?可以设置为NULL,具体解释见MSDN,

但如果不为空如何加载呢?

示例如下:

#define SYMPATH "%SYSTEMROOT%;.\\Symbols\\;..\\Symbols\\;..\\..\\Symbols\\;..\\..\\..\\Symbols\\"

ExpandEnvironmentStringsA(SYMPATH, symPath, sizeof(symPath));

这个API的功能是扩展环境变量的取值,通俗一点将就是获取变量值。

至于字符串是什么含义,请查询环境变量相关变量含义。

查询异常处理信息:

首先查询异常信息需要一定的windebug基础。

https://blog.csdn.net/sunboyhch/article/details/37914727

查询具体异常的一般流程为:

miniDump的具体操作流程是这样:
1、打开异常dump文件
2、导入pdb符号文件
3、输入!analyze -v 命令分析出错原因,堆栈信息、出错位置,以及包含错误位置的文件。
4、然后通过文件菜单打开文件。
5、输入.ecxr 关联
6、kp命令。输出详细的错误信息。
第二种方法是
1、直接输入.excr直接通过dump文件的记录的索引关联源文件。
2、输入kp命令查看详细的堆栈错误信息

在异常处理的过程中。还需要了解一些其他的知识,如dos文件头、PE文件格式等等。推荐博客链接如下:

https://blog.csdn.net/chenlycly/article/details/53378196

bool CrashHandleCls::GetLogicalAddress(PVOID pLinearAddress,PTSTR pszModule,DWORD dwModuleNameLen,DWORD_PTR& dwSection,DWORD_PTR& dwOffset){

MEMORY_BASIC_INFORMATION mbi;

if(!::VirtualQuery(pLinearAddress,&mbi,sizeof(mbi)))return false;

DWORD_PTR hModule=(DWORD_PTR)mbi.AllocationBase;//获取页面起始地址

//验证访问权限

if(IsBadReadPtr((const void *)hModule,sizeof(IMAGE_DOS_HEADER))) {

_tcsncpy(pszModule,_T("Unknown"),dwModuleNameLen);

dwSection=0;

dwOffset=0;

return false;

}

//获取完整的路径

if(!::GetModuleFileNameW((HMODULE)hModule,pszModule,dwModuleNameLen))return false;

PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hModule;//转换为DOS文件结构

PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)(hModule + pDosHdr->e_lfanew); //获取PE文件的文件头 PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNtHdr);//定位区块表(节表)

DWORD_PTR dwRVA = (DWORD_PTR)pLinearAddress - hModule;//获取偏移地址

//pNtHdr->FileHeader.NumberOfSections 获取节表总数

for(UINT i = 0; i < pNtHdr->FileHeader.NumberOfSections; i++, pSection++)

{

DWORD_PTR dwSectionStart = pSection->VirtualAddress;//获取目标在内存中的开始地址(节区的 RVA 地址)

DWORD_PTR dwSectionEnd = dwSectionStart +

max(pSection->SizeOfRawData, pSection->Misc.VirtualSize);//获取目标在内存中的结束地

if((dwRVA >= dwSectionStart) && (dwRVA <= dwSectionEnd)) {

dwSection = i + 1;

dwOffset = dwRVA - dwSectionStart;//获取偏移量

return TRUE;

}

}

dwSection = 0;

dwOffset = 0;

return FALSE;

}

MiniDump文件的创建、分析堆栈信息、定位错误、查看异常处理信息相关推荐

  1. linux查看显示器名称命令,linux 查看显示器信息Linux下查看硬件信息命令大全

    /proc 虚拟的目录,是系统内存的映射.可直接访问这个目录来获取系统信息.其中也包含下面的信息: 主机CPU信息:cpuinfo 主机DMA通道信息:dma 文件系统信息:filesystems 主 ...

  2. think.class.php错误,thinkphp源码分析(四)—错误及异常处理篇

    源码分析 错误及异常处理机制 错误及异常处理机制文件是/thinkphp/library/think/Error.php,在框架引导文件的的基础文件base.php中注册(不知道的可以去看<&l ...

  3. thinkphp 源码分析(四)—— 错误和异常处理 以及 log 日志

    0x01 前言 本来是这样的,继续是smile 师傅的那篇文章,文章中提到了可以用包含日志, 但是一开始我输入: http://127.0.0.1/public/index.php/index/ind ...

  4. linux 下查看应用版本信息,Linux下查看版本信息

    Linux下如何查看版本信息, 包括位数.版本信息以及CPU内核信息.CPU具体型号等. 1.# uname -a   (Linux查看版本当前操作系统内核信息) 2.# cat /proc/vers ...

  5. ubantu获取信息_Ubuntu 下查看CPU 信息命令

    查看当前操作系统内核信息 uname -a Linux redcat 2.6.31-20-generic #58-Ubuntu SMP Fri Mar 12 05:23:09 UTC 2010 i68 ...

  6. linux查看进程详细信息top,linux查看系统进程信息命令 px,top详解

    linux查看系统进程信息命令 px,top详解 发表于:2011-03-10来源:作者:点击数: linux查看系统进程信息命令 px,top详解 软件测试 ps ax命令是显示一个当前系统进程的列 ...

  7. linux 查看numa信息,Linux中查看NUMA信息

    Linux中查看NUMA信息 2015-03-19 本博客所有文章采用的授权方式为 自由转载-非商用-非衍生-保持署名 ,转载请务必注明出处,谢谢. 声明: 本博客欢迎转发,但请保留原作者信息! 新浪 ...

  8. linux 网卡硬件信息失败,linux 查看硬件信息,网卡、CPU、硬盘

    查看网卡型号 [root@server]# lspci | grep Ethernet 00:19.0 Ethernet controller: Intel Corporation 82567V-2 ...

  9. linux系统查看机器硬件信息,linux系统查看硬件信息的方法

    用过Linux系统的人都知道这么一个情况,那就是Linux大部分操作是通过命令实现的,并不像Windows那么直观.linux查看硬件信息也是需要通过命令查询才可以看得到硬件的信息,那linux系统如 ...

最新文章

  1. c语言fd变量,有哪位大神会用FD程序包计算功能多样性呀,在线等......
  2. BZOJ 3456 城市规划 (组合计数、DP、FFT)
  3. linux useradd命令使用示例
  4. mysql 5.x数据库安装_Ubuntu 12.04 mysql 源码安装--mysql.5.5.x
  5. 彻底禁用chrome请停用以开发者模式运行的扩展程序弹框
  6. 利用WireShark破解网站密码
  7. MAC M1 安装 matlab2020a
  8. 高二计算机考试题库和答案,2017计算机基础考试题库及答案
  9. 城市公交类毕业论文文献都有哪些?
  10. 第三届上海大学生网络安全大赛 流量分析
  11. sox处理mp3_音频处理利器--SoX
  12. 网站蜘蛛日志分析解读,SEO站长自查诊断
  13. 简单爬取小姐姐的照片
  14. Scala 令人着迷的类设计
  15. matches()方法的使用规则
  16. 51单片机 | LED点阵实验 | 点亮一个点 | 显示数字 | 显示图像
  17. MATLAB中关于patch的用法(涉及vertice,faces等的基础的介绍)
  18. 别让自己 “墙” 了自己
  19. 室外无线覆盖解决方案
  20. 用Python分析完6000 款 App,得出这些结论

热门文章

  1. Anaconda无法通过activate激活虚拟环境解决方案
  2. 非常暧昧的两个人(同事)关系突然就疏远
  3. ms sql java_java连接ms sql server各类问题解析
  4. 数值计算实验_完整的列表计算程序,计算lnx导数,3种方法计算调和级数
  5. 数学建模论文写作学习——论文题目、关键词、摘要写作学习
  6. arguments的用法总结
  7. JSFL自动绘画_5_黄金分割
  8. java计算机毕业设计汽车金融人事管理源码+系统+数据库+lw文档+mybatis+运行部署
  9. ulimit: file size: cannot modify limit: Operation not permitted 修改ulimit -f 时报错
  10. 2011孕妇奶粉排行榜