`
scorpiomiracle
  • 浏览: 264183 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

VS 2005使用map文件查找程序崩溃原因(转载,很好)

阅读更多
一般程序崩溃可以通过debug,找到程序在那一行代码崩溃了,最近编一个多线程的程序,都不知道在那发生错误,多线程并发,又不好单行调试,终于找到一个比较好的方法来找原因,通过生成map文件,由于2005取消map文件生成行号信息(vc6.0下是可以生成行号信息的,不知道microsoft怎么想的,在2005上取消了),只能定位在那个函数发生崩溃。这里可以通过生成cod文件,即机器码这一文件,具体定位在那一行崩溃。

首先配置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),生成机器,源代码。

上面所说的 property 是“项目”菜单下的 property,而非“工具”菜单下的 property。(转者注)

简单例子:
#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程序发生崩溃。

具体步骤:
(1)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)找出具体崩溃行号.

由(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文件找到程序崩溃原因。


分享到:
评论

相关推荐

    使用map文件查找程序崩溃原因

    一般程序崩溃可以通过debug,找到程序在那一行代码崩溃了,最近编一个多线程的程序,都不知道在那发生错误,多线程并发,又不好单行调试,终于找到一个比较好的方法来找原因,通过生成map文件,由于2005取消map文件...

    VS中通过map文件找到崩溃的代码行

    通过以上步骤,我们可以有效地利用VS中的Map文件和Cod文件来定位程序崩溃的原因和具体位置。这种方法不仅可以提高问题诊断的速度,还能帮助开发者更好地理解编译后的程序结构,从而提升整体的编程技能。希望这些步骤...

    msjexhnd Windows进程崩溃时捕获并输出错误信息、函数调用栈的例子

    一个在Windows进程崩溃时捕获并输出错误信息、函数调用栈的例子。对你制作自己的错误报告机制非常有用 ...注意编译时开启“生成调试信息”,推荐生成map,可根据map文件里面的函数地址来更好的查找崩溃的函数。

    c++编写的电话本操作,具有相关文件操作

    总的来说,这个C++电话本项目是一个很好的实践案例,涵盖了数据结构、文件操作、异常处理和面向对象设计等多个核心编程概念。对于初学者和经验丰富的开发者来说,都是一个有价值的参考资料。通过理解和实现这样的...

    GPA.rar_gpa

    《C++实现的GPA学分转换器...总结,"GPA.rar_gpa"项目展示了C++在实际问题解决中的应用,涵盖了面向对象编程、文件操作、数据结构与算法、异常处理等多个核心知识点,对于学习和提升C++编程技能具有很好的实践价值。

    学生成绩管理系统C++ 源码(很完整)

    【学生成绩管理系统C++ 源码解析】 在计算机科学与信息技术领域,开发一个...此外,对于想要进一步学习软件工程、数据库管理或者Web应用开发的学生,这个项目也是一个很好的起点,因为很多基础原理和技术都是相通的。

    人事管理源码 c++

    4. **异常处理**:良好的代码应包含异常处理机制,以确保在遇到错误时能优雅地处理,防止程序崩溃。C++的try-catch语句块用于捕获和处理异常。 5. **标准库的使用**:C++标准库提供了许多便利的功能,如排序、搜索...

    C++版本标准库文件查询资料

    "**C++标准库.chm**"这个文件很可能是一个帮助文档,包含了C++标准库的详细信息,包括每个函数的原型、参数、返回值以及使用示例。对于学习和查阅C++标准库非常有帮助。通过查阅这个文档,开发者可以深入理解各个...

    C++课程设计 学生成绩系统

    6. **异常处理**:在处理用户输入或文件操作时,可能需要使用try-catch块进行异常处理,以确保程序在遇到错误时不会崩溃。 7. **算法**:可能涉及到排序算法,如冒泡排序、选择排序或快速排序,用于按成绩排序学生...

    基于C++实现(控制台)图书管理系统【100010188】

    例如,可以使用数组或链表来存储读者和图书的信息,使用映射(map)或关联数组(associative array)来实现快速查找功能。此外,还需要设计高效的算法处理增删改查等操作。 5. **文件操作**: 在实际应用中,信息...

    c++学生成绩管理系统_成绩管理系统_学生成绩管理系统_

    《C++学生成绩管理系统详解》 在信息技术领域,学生管理系统是常见的应用之一,而C++作为一门强大的编程语言,常被用来开发此类系统。本文将深入探讨如何使用C++...对于初学者而言,这是一个很好的学习和实践平台。

    ccfcsp 历年真题解答 C++版本.zip

    9. **内存管理**:指针的使用、动态内存分配与释放、堆与栈的理解,了解内存管理可以帮助避免内存泄漏和程序崩溃。 10. **编译与链接**:理解预处理器、编译器、链接器的工作原理,有助于解决编译和运行时的问题。 ...

    c++ 控制台实现学生管理

    对于初学者来说,这个项目是一个很好的实践平台,能够全面锻炼到C++编程的各种技能。随着技术水平的提高,可以考虑进一步优化,如引入图形用户界面(GUI)或者使用SQLite等轻量级数据库来存储数据,以提供更复杂的...

    jiazu.rar_C Builder_族谱c 代码_族谱c++

    例如,`FamilyTree`类可能使用泛型容器(如`std::map`)来存储成员,便于快速查找和访问;异常处理可以确保在出现错误时,程序不会突然崩溃,而是给出有意义的错误信息。 对于初学者而言,通过阅读和理解这段代码,...

    简易学生管理系统源码 数据结构 大作业 学籍管理 C++

    这个系统可能涵盖了基础的数据存储、查询、更新和删除功能,对于理解如何在实际应用中运用数据结构有很好的帮助。 在C++中,数据结构是编程的基础,它涉及如何有效地组织和存储数据以便于访问和处理。在这个项目中...

    Bank_java_源码

    总的来说,"Bank_java_源码"项目是一个很好的实践平台,它涵盖了Java编程基础,如类的设计、对象的创建、方法的使用,以及异常处理等关键概念。对于初学者来说,通过分析和理解这个项目,不仅可以提升编程技能,还能...

    hero_java学生.rar_java 学生成绩_学生成绩管理系统_学生成绩管理系统 java_学生成绩管理系统 j_成绩管

    在这个“hero_java学生.rar”压缩包中,我们找到了一个针对初学者的学生成绩管理系统,这是一个很好的实践项目,可以帮助学习者深入理解Java编程以及软件开发的基本原理。 首先,学生成绩管理系统的核心功能通常...

    c++帮助手册

    当程序出现错误或异常情况时,异常处理机制可以捕获并处理这些错误,避免程序崩溃。`try`、`catch`和`throw`关键字是C++异常处理的基础。 此外,C++还有预处理器(预编译指令,如`#include`、`#define`等)、命名...

    数据结构之图书管理系统

    这个系统对于计算机科学与技术专业的学生来说,是一个很好的实践平台,能够提升他们对数据结构的理解和编程能力。 在数据结构方面,此项目可能涉及到以下关键知识点: 1. **链表**:图书信息可能以链表的形式存储...

    1~10题.zip

    标题 "1~10题.zip" 暗示这是一个包含一系列编程题目解答的压缩文件,很可能是某个编程挑战或竞赛的解决方案集合。由于没有具体的标签信息,我们可以根据常见的编程题目类型来推测这些文件可能涉及的知识点。 1. **...

Global site tag (gtag.js) - Google Analytics