通过map文件找程序崩溃的代码行

 

一,配置vs

 

 

 

二,程序崩溃界面

 

// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>


void fun(bool flag)
{
    if (flag) {
        printf("hello world\n");
    }
    else {
        printf("sorry.\n");
    }
    int a = 0, b = 4;
    int c = b / a;
}

int main()
{
    bool m = false;
    fun(m);
    //std::cout << "Hello World!\n";
    system("pause");
    return 0;
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件

 

 

三,map文件

0003:00000030 00000388H .bss                    DATA
 0004:00000000 0000002dH .msvcjmc                DATA
 0005:00000000 00000060H .rsrc$01                DATA
 0005:00000060 00000180H .rsrc$02                DATA

  Address         Publics by Value              Rva+Base       Lib:Object

 0000:00000000       ___hybrid_code_map_count   00000000     <absolute>
 0000:00000000       ___AbsoluteZero            00000000     <absolute>
 0000:00000000       ___hybrid_code_map         00000000     <absolute>
 0000:00000000       ___volatile_metadata       00000000     <absolute>
 0000:00000000       ___hybrid_auxiliary_iat    00000000     <absolute>
 0000:00000000       ___guard_longjmp_count     00000000     <absolute>
 0000:00000000       ___dynamic_value_reloc_table 00000000     <absolute>
 0000:00000000       ___guard_iat_count         00000000     <absolute>
 0000:00000000       ___enclave_config          00000000     <absolute>
 0000:00000000       ___guard_fids_count        00000000     <absolute>
 0000:00000000       ___guard_longjmp_table     00000000     <absolute>
 0000:00000000       ___guard_iat_table         00000000     <absolute>
 0000:00000000       ___guard_fids_table        00000000     <absolute>
 0000:00000002       ___safe_se_handler_count   00000002     <absolute>
 0000:00000100       ___guard_flags             00000100     <absolute>
 0000:00000000       ___ImageBase               00400000     <linker-defined>
 0001:00000000       ?__empty_global_delete@@YAXPAX@Z 00401000 f i ConsoleApplication1.obj
 0001:00000040       ?__empty_global_delete@@YAXPAXI@Z 00401040 f i ConsoleApplication1.obj
 0001:00000080       ?fun@@YAX_N@Z              00401080 f   ConsoleApplication1.obj
 0001:00000100       __JustMyCode_Default       00401100 f i ConsoleApplication1.obj
 0001:00000110       ___local_stdio_printf_options 00401110 f i ConsoleApplication1.obj
 0001:00000160       __vfprintf_l               00401160 f i ConsoleApplication1.obj
 0001:000001d0       _main                      004011d0 f   ConsoleApplication1.obj
 0001:00000240       _printf                    00401240 f i ConsoleApplication1.obj
 0001:000002c0       @__CheckForDebuggerJustMyCode@4 004012c0 f   MSVCRTD:debugger_jmc.obj
 0001:00000300       @_RTC_AllocaHelper@12      00401300 f   MSVCRTD:stack.obj
 0001:00000340       @_RTC_CheckStackVars2@12   00401340 f   MSVCRTD:stack.obj
 0001:00000420       @_RTC_CheckStackVars@8     00401420 f   MSVCRTD:stack.obj
 0001:00000490       __RTC_CheckEsp             00401490 f   MSVCRTD:stack.obj

如果仔细浏览 Rva+Base 这栏,你会发现第一个比崩溃地址大的地址0x00401080,所以在 这个地址之前的那个入口就是产生崩溃的函数

因此,发生崩溃的函数就是 ?Crash@@YAXXZ ,所有以问号开头的函数名称都是 C++ 修饰的名称

 

什么是 MAP 文件?简单地讲, MAP 文件是程序的全局符号、源文件和代码行号信息的唯一的文本表示方法,它可以在任何地方、任何时候使用,不需要有额外的程序进行支持。而且,这是唯一能找出程序崩溃的地方的救星。

好吧,既然 MAP 文件如此神奇,那么我们应该如何生成它呢?在 VC 中,我们可以按下 Alt+F7 ,打开“Project Settings”选项页,选择 C/C++ 选项卡,并在最下面的 Project Options 里面输入:/Zd ,然后要选择 Link 选项卡,在最下面的 Project Options 里面输入: /mapinfo:lines 和 /map:PROJECT_NAME.map 。最后按下 F7 来编译生成 EXE 可执行文件和 MAP 文件。

在 MASM 中,我们要设置编译和连接参数,我通常是这样做的:

rc %1.rc
ml /c /coff /Zd %1.asm
link /subsystem:windows /mapinfo:exports /mapinfo:lines /map:%1.map %1.obj %1.res

把它保存成 makem.bat ,就可以在命令行输入 makem filename 来编译生成 EXE 可执行文件和 MAP 文件了。

在此我先解释一下加入的参数的含义:

/Zd 表示在编译的时候生成行信息
/map[:filename] 表示生成 MAP 文件的路径和文件名
/mapinfo:lines 表示生成 MAP 文件时,加入行信息
/mapinfo:exports 表示生成 MAP 文件时,加入 exported functions (如果生成的是 DLL 文件,这个选项就要加上)

参考:

https://blog.csdn.net/anddy926/article/details/7695476/
https://blogs.msdn.microsoft.com/hopperx/2006/09/14/using-map-files-part-1/

https://blog.csdn.net/u012138730/article/details/90611728

 

posted @ 2019-06-27 14:24  狂奔~  阅读(922)  评论(0编辑  收藏  举报