windows下如何分析应用程序崩溃

最近在开发一个大型网络服务器程序,同时支持windows服务器和linux服务器。

程序为分布式结构,多个可执行程序合作完成服务,逻辑比较复杂,多线程,重复杂,状态迁移繁多。

初期,每当用户增加,程序就隔三差五的崩溃。

对于这样的程序,如果查找bug,分析崩溃的原因?

大的来说,应该从两方面入手:

一,做好应用程序的日志记录,从应用程序的运行轨迹分析程序bug,这种方法因应用而异,不具体讨论

二,利用系统日志和系统工具,结合开发环境提供的debug支持。

 

具体到平台,今天讲一下windows服务器下的一些技巧。

windows下:

1,可以利用drwtsn工具,记录下程序出错时候的线程编号,堆栈数据来分析崩溃的原因。具体过程下期再讲

2,结合vs开发环境提供的map文件、cod文件,分析bug,今天具体说一下这个技巧。

 

首先配置vc2005生成map文件和cod文件:

(1).map文件:property->Configuration Properties->Linker->Debugging 中的Generate Map File选择Yes(/MAP);

(2).cod文件:property->Configuration Properties->C/C++->output Files中Assembler OutPut中选择Assembly,Maching Code and Source(/FAcs),生成机器,源代码。

例子程序:

#include "stdafx.h"

void errorFun(int * p)
{
*p=1;
}

int _tmain(int argc, _TCHAR* argv[])
{
int * p=NULL;
errorFun(p);
return 0;
}

在errorFun中函数中,*p=1这一行出错,由于p没有申请空间,运行时出错,弹出

Unhandled exception at 0x004113b1 in testError.exe: 0xC0000005: Access violation writing location 0x00000000.

在0x004113b1程序发生崩溃。

debug文件下打开map文件,定位崩溃函数.

map文件开头是一些链接信息,然后我们要找函数和实始地址信息。地址是函始的开始地址

Address         Publics by Value              Rva+Base       Lib:Object

0000:00000000       ___safe_se_handler_count   00000000     <absolute>
0000:00000000       ___safe_se_handler_table   00000000     <absolute>
0000:00000000       ___ImageBase               00400000     <linker-defined>
0001:00000000       __enc$textbss$begin        00401000     <linker-defined>
0001:00010000       __enc$textbss$end          00411000     <linker-defined>
0002:00000390       ?errorFun@@YAXPAH@Z        00411390 f   testError.obj
0002:000003d0       _wmain                     004113d0 f   testError.obj
0002:00000430       __RTC_InitBase             00411430 f   MSVCRTD:init.obj
0002:00000470       __RTC_Shutdown             00411470 f   MSVCRTD:init.obj
0002:00000490       __RTC_CheckEsp             00411490 f   MSVCRTD:stack.obj
0002:000004c0       @_RTC_CheckStackVars@8     004114c0 f   MSVCRTD:stack.obj
0002:00000540       @_RTC_AllocaHelper@12      00411540 f   MSVCRTD:stack.obj

....

程序崩溃地址0x004113b1,我们找到第一个比这个地址大的004113d0,前一个是00411390,地址是函数的开始地址,所以发生的崩溃的的函数是errorFun,这个函数的初始地址00411390.

找出具体崩溃行号.

由(2)可知,发生错误函数是errorFun,在testError.obj,打开testError.cod文件,找到errorFun函数生成的机器码.

?errorFun@@YAXPAH@Z PROC    ; errorFun, COMDAT

; 7    : {

00000 55   push ebp
00001 8b ec   mov ebp, esp
00003 81 ec c0 00 00
00   sub esp, 192 ; 000000c0H
00009 53   push ebx
0000a 56   push esi
0000b 57   push edi
0000c 8d bd 40 ff ff
ff   lea edi, DWORD PTR [ebp-192]
00012 b9 30 00 00 00 mov ecx, 48   ; 00000030H
00017 b8 cc cc cc cc mov eax, -858993460 ; ccccccccH
0001c f3 ab   rep stosd

; 8    : *p=1;

0001e 8b 45 08 mov eax, DWORD PTR _p$[ebp]
00021 c7 00 01 00 00
00   mov DWORD PTR [eax], 1

; 9    : }

00027 5f   pop edi
00028 5e   pop esi
00029 5b   pop ebx
0002a 8b e5   mov esp, ebp
0002c 5d   pop ebp
0002d c3   ret 0
说明: 7,8,9是表示在源代码的行号。00000 55   push ebp,000000是相对偏移地地,55是机器码号,push ebp,000000是汇编码。

通过(2)我们计算相对偏移地址:即崩溃地址-函数起始地址,0x004113b1-0x00411390=0x21(16进制的计数)

找到0x21这一行对应的机器码是 00021 c7 00 01 00 00,向上看它是由第8行*p=1;生成的汇编码,由此可见是这一行程序发生崩溃。

总结:当然这只是一个简单的例子,实际上一运行便知道是这一行出错,但是对于一个比较大的工程,特别是在多线程并发情况下,要找出那一行出错比较困难,便可以使用map和cod文件找到程序崩溃原因。

 

转载于:https://www.cnblogs.com/codetech/archive/2010/11/07/1871081.html

Windows 平台上,应用程序崩溃时可能会产生 Core Dump 文件,通常以 .dmp 后缀结尾。这个文件包含了应用程序崩溃时的内存状态,可以帮助开发者定位和解决问题。以下是处理 Windows 应用程序崩溃产生 Core Dump 的一些方法: 1. 启用 Windows Core Dump 在 Windows 上,默认情况下是不启用 Core Dump 的。使用以下命令可以启用 Core Dump: ``` reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpType /t REG_DWORD /d 2 /f ``` 2. 使用 Visual Studio 调试 Core Dump Visual Studio 支持使用 Core Dump 进行调试。可以使用 Visual Studio 打开 Core Dump 文件,并分析崩溃原因。具体的操作步骤可以参考 Microsoft 官方文档。 3. 使用 WinDbg 调试 Core Dump WinDbg 是一款微软开发的用于 Windows 平台上的调试器,支持分析 Core Dump 文件。可以使用 WinDbg 打开 Core Dump 文件,并分析崩溃原因。具体的操作步骤可以参考微软官方文档。 4. 使用第三方工具分析 Core Dump 除了使用 Visual Studio 和 WinDbg,还有一些第三方工具可以用来分析 Core Dump 文件,比如 Process Explorer、GDB 等。这些工具都有各自的优缺点,开发者可以根据自己的需要选择合适的工具。 总的来说,处理 Windows 应用程序崩溃产生 Core Dump 的过程比较复杂,需要开发者具备一定的调试经验。建议在处理 Core Dump 之前先了解一下相关的调试工具和技术。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值