利用map文件找到程序崩溃代码行

vs2010利用map,cod文件定位崩溃代码行 利用map,cod文件定位崩溃代码行 利用vs2010 新建一个空的控制台项目,添加文件gtg.cpp,内容如下 void crash() {          inti=1;          intj=0;          i/=j; } int main() {          crash();          return0; } 配置生成map及cod文件 阅读详情
一般程序崩溃可以通过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。(转者注) 

简单例子:C++代码

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


补充:

读了老罗的“仅通过崩溃地址找出源代码的出错行”(下称"罗文")一文后,感觉该文还是可以学到不少东西的。不过文中尚存在有些说法不妥,以及有些操作太繁琐的地方 。为此,本人在学习了此文后,在多次实验实践基础上,把该文中的一些内容进行补充与改进,希望对大家调试程序,尤其是release版本的程序有帮助 。欢迎各位朋友批评指正。

一、该方法适用的范围

在windows程序中造成程序崩溃的原因很多,而文中所述的方法仅适用与:由一条语句当即引起的程序崩溃。如原文中举的除数为零的崩溃例子。而笔者在实际工作中碰到更多的情况是:指针指向一非法地址 ,然后对指针的内容进行了,读或写的操作。例如:

1.void Crash1()
2.{
3.char * p =(char*)100;
4.*p=100;
5.}

这些原因造成的崩溃,无论是debug版本,还是release版本的程序,使用该方法都可找到造成崩溃的函数或子程序中的语句行,具体方法的下面还会补充说明。 另外,实践中另一种常见的造成程序崩溃的原因:函数或子程序中局部变量数组越界付值,造成函数或子程序返回地址遭覆盖,从而造成函数或子程序返回时崩溃。例如:

01.#include
02.void Crash2();
03.int main(int argc,char* argv[])
04.{
05.Crash2();
06.return 0;
07.}
08. 
09.void Crash2()
10.{
11.char p[1];
12.strcpy(p,"0123456789");
13.}

在vc中编译运行此程序的release版本,会跳出如下的出错提示框。

图一 上面例子运行结果

这里显示的崩溃地址为:0x34333231。这种由前面语句造成的崩溃根源,在后续程序中方才显现出来的情况,显然用该文所述的方法就无能为力了。不过在此例中多少还有些蛛丝马迹可寻找到崩溃的原因:函数Crash2中的局部数组p只有一个字节大小 ,显然拷贝"0123456789"这个字符串会把超出长度的字符串拷贝到数组p的后面,即*(p+1)=''1'',*(p+2)=''2'',*(p+3)=''3'',*(p+4)=4。。。。。。而字符''1''的ASC码的值为0x31,''2''为0x32,''3''为0x33,''4''为0x34。。。。。,由于intel的cpu中int型数据是低字节保存在低地址中 ,所以保存字符串''1234''的内存,显示为一个4字节的int型数时就是0x34333231。显然拷贝"0123456789"这个字符串时,"1234"这几个字符把函数Crash2的返回地址给覆盖 ,从而造成程序崩溃。对于类似的这种造成程序崩溃的错误朋友们还有其他方法排错的话,欢迎一起交流讨论。

二、设置编译产生map文件的方法

该文中产生map文件的方法是手工添加编译参数来产生map文件。其实在vc6的IDE中有产生map文件的配置选项的。操作如下:先点击菜单"Project"->"Settings。。。",弹出的属性页中选中"Link"页 ,确保在"category"中选中"General",最后选中"Generate mapfile"的可选项。若要在在map文件中显示Line numbers的信息的话 ,还需在project options 中加入/mapinfo:lines 。Line numbers信息对于"罗文"所用的方法来定位出错源代码行很重要 ,但笔者后面会介绍更加好的方法来定位出错代码行,那种方法不需要Line numbers信息。

图二 设置产生MAP文件

三、定位崩溃语句位置的方法

"罗文"所述的定位方法中,找到产生崩溃的函数位置的方法是正确的,即在map文件列出的每个函数的起始地址中,最近的且不大于崩溃地址的地址即为包含崩溃语句的函数的地址 。但之后的再进一步的定位出错语句行的方法不是最妥当,因为那种方法前提是,假设基地址的值是 0x00400000 ,以及一般的 PE 文件的代码段都是从 0x1000偏移开始的 。虽然这种情况很普遍,但在vc中还是可以基地址设置为其他数,比如设置为0x00500000,这时仍旧套用

1.崩溃行偏移 = 崩溃地址 - 0x00400000 - 0x1000

的公式显然无法找到崩溃行偏移。 其实上述公式若改为

1.崩溃行偏移 = 崩溃地址 - 崩溃函数绝对地址 + 函数相对偏移

即可通用了。仍以"罗文"中的例子为例:"罗文"中提到的在其崩溃程序的对应map文件中,崩溃函数的编译结果为

1.0001:00000020 ?Crash@@YAXXZ 00401020 f CrashDemo。obj

对与上述结果,在使用我的公式时 ,"崩溃函数绝对地址"指00401020, 函数相对偏移指 00000020, 当崩溃地址= 0x0040104a时, 则 崩溃行偏移 = 崩溃地址 - 崩溃函数起始地址+ 函数相对偏移 = 0x0040104a - 0x00401020 + 0x00000020= 0x4a,结果与"罗文"计算结果相同 。但这个公式更通用。

四、更好的定位崩溃语句位置的方法。

其实除了依靠map文件中的Line numbers信息最终定位出错语句行外,在vc6中我们还可以通过编译程序产生的对应的汇编语句,二进制码,以及对应c/c++语句为一体的"cod"文件来定位出错语句行 。先介绍一下产生这种包含了三种信息的"cod"文件的设置方法:先点击菜单"Project"->"Settings。。。",弹出的属性页中选中"C/C++"页 ,然后在"Category"中选则"Listing Files",再在"Listing file type"的组合框中选择"Assembly,Machine code, and source"。接下去再通过一个具体的例子来说明这种方法的具体操作。

图三 设置产生"cod"文件

准备步骤1)产生崩溃的程序如下:

01.01 //****************************************************************
02.02 //文件名称:crash。cpp
03.03 //作用:    演示通过崩溃地址找出源代码的出错行新方法
04.04 //作者:   伟功通信 roc
05.05 //日期:   2005-5-16
06.06//****************************************************************
07.07 void Crash1();
08.08 int main(int argc,char* argv[])
09.09 {
10.10  Crash1();
11.11  return 0;
12.12 }
13.13
14.14 void Crash1()
15.15 {
16.16  char * p =(char*)100;
17.17  *p=100;
18.18 }

准备步骤2)按本文所述设置产生map文件(不需要产生Line numbers信息)。

准备步骤3)按本文所述设置产生cod文件。

准备步骤4)编译。这里以debug版本为例(若是release版本需要将编译选项改为不进行任何优化的选项,否则上述代码会因为优化时看作废代码而不被编译,从而看不到崩溃的结果),编译后产生一个"exe"文件 ,一个"map"文件,一个"cod"文件。

运行此程序,产生如下如下崩溃提示:

图四 上面例子运行结果

排错步骤1)定位崩溃函数。可以查询map文件获得。我的机器编译产生的map文件的部分如下:

01.Crash
02. 
03.Timestamp is 42881a01 (Mon May 16 11:56:49 2005)
04. 
05.Preferred load address is 00400000
06. 
07.Start Length Name Class
08.0001:00000000 0000ddf1H .text CODE
09.0001:0000ddf1 0001000fH .textbss CODE
10.0002:00000000 00001346H .rdata DATA
11.0002:00001346 00000000H .edata DATA
12.0003:00000000 00000104H .CRT$XCA DATA
13.0003:00000104 00000104H .CRT$XCZ DATA
14.0003:00000208 00000104H .CRT$XIA DATA
15.0003:0000030c 00000109H .CRT$XIC DATA
16.0003:00000418 00000104H .CRT$XIZ DATA
17.0003:0000051c 00000104H .CRT$XPA DATA
18.0003:00000620 00000104H .CRT$XPX DATA
19.0003:00000724 00000104H .CRT$XPZ DATA
20.0003:00000828 00000104H .CRT$XTA DATA
21.0003:0000092c 00000104H .CRT$XTZ DATA
22.0003:00000a30 00000b93H .data DATA
23.0003:000015c4 00001974H .bss DATA
24.0004:00000000 00000014H .idata$2 DATA
25.0004:00000014 00000014H .idata$3 DATA
26.0004:00000028 00000110H .idata$4 DATA
27.0004:00000138 00000110H .idata$5 DATA
28.0004:00000248 000004afH .idata$6 DATA
29. 
30.Address Publics by Value Rva+Base Lib:Object
31. 
32.0001:00000020 _main 00401020 f Crash.obj
33.0001:00000060 ?Crash1@@YAXXZ 00401060 f Crash.obj
34.0001:000000a0 __chkesp 004010a0 f LIBCD:chkesp.obj
35.0001:000000e0 _mainCRTStartup 004010e0 f LIBCD:crt0.obj
36.0001:00000210 __amsg_exit 00401210 f LIBCD:crt0.obj
37.0001:00000270 __CrtDbgBreak 00401270 f LIBCD:dbgrpt.obj
38....

对于崩溃地址0x00401082而言,小于此地址中最接近的地址(Rva+Base中的地址)为00401060,其对应的函数名为?Crash1@@YAXXZ,由于所有以问号开头的函数名称都是 C++ 修饰的名称 ,"@@YAXXZ"则为区别重载函数而加的后缀,所以?Crash1@@YAXXZ就是我们的源程序中,Crash1() 这个函数。

排错步骤2)定位出错行。打开编译生成的"cod"文件,我机器上生成的文件内容如下:

001.TITLE   E:\Crash\Crash。cpp
002..386P
003.include listing.inc
004.if @Version gt 510
005..model FLAT
006.else
007._TEXT   SEGMENT PARA USE32 PUBLIC ''CODE''
008._TEXT   ENDS
009._DATA   SEGMENT DWORD USE32 PUBLIC ''DATA''
010._DATA   ENDS
011.CONST   SEGMENT DWORD USE32 PUBLIC ''CONST''
012.CONST   ENDS
013._BSS    SEGMENT DWORD USE32 PUBLIC ''BSS''
014._BSS    ENDS
015.$$SYMBOLS   SEGMENT BYTE USE32 ''DEBSYM''
016.$$SYMBOLS   ENDS
017.$$TYPES SEGMENT BYTE USE32 ''DEBTYP''
018.$$TYPES ENDS
019._TLS    SEGMENT DWORD USE32 PUBLIC ''TLS''
020._TLS    ENDS
021.;   COMDAT _main
022._TEXT   SEGMENT PARA USE32 PUBLIC ''CODE''
023._TEXT   ENDS
024.;   COMDAT ?Crash1@@YAXXZ
025._TEXT   SEGMENT PARA USE32 PUBLIC ''CODE''
026._TEXT   ENDS
027.FLAT    GROUP _DATA, CONST, _BSS
028.ASSUME  CS: FLAT, DS: FLAT, SS: FLAT
029.endif
030.PUBLIC  ?Crash1@@YAXXZ                  ; Crash1
031.PUBLIC  _main
032.EXTRN   __chkesp:NEAR
033.;   COMDAT _main
034._TEXT   SEGMENT
035._main   PROC NEAR                   ; COMDAT
036. 
037.; 9    : {
038. 
039.00000 55       push    ebp
040.00001 8b ec        mov     ebp, esp
041.00003 83 ec 40     sub     esp, 64            ; 00000040H
042.00006 53       push    ebx
043.00007 56       push    esi
044.00008 57       push    edi
045.00009 8d 7d c0     lea     edi, DWORD PTR [ebp-64]
046.0000c b9 10 00 00 00   mov     ecx, 16            ; 00000010H
047.00011 b8 cc cc cc cc   mov     eax, -858993460        ; ccccccccH
048.00016 f3 ab        rep stosd
049. 
050.; 10   :    Crash1();
051. 
052.00018 e8 00 00 00 00   call    ?Crash1@@YAXXZ     ; Crash1
053. 
054.; 11   :    return 0;
055. 
056.0001d 33 c0        xor     eax, eax
057. 
058.; 12   : }
059. 
060.0001f 5f       pop     edi
061.00020 5e       pop     esi
062.00021 5b       pop     ebx
063.00022 83 c4 40     add     esp, 64            ; 00000040H
064.00025 3b ec        cmp     ebp, esp
065.00027 e8 00 00 00 00   call    __chkesp
066.0002c 8b e5        mov     esp, ebp
067.0002e 5d       pop     ebp
068.0002f c3       ret     0
069._main   ENDP
070._TEXT   ENDS
071.;   COMDAT ?Crash1@@YAXXZ
072._TEXT   SEGMENT
073._p$ = -4
074.?Crash1@@YAXXZ PROC NEAR                ; Crash1, COMDAT
075. 
076.; 15   : {
077. 
078.00000 55       push    ebp
079.00001 8b ec        mov     ebp, esp
080.00003 83 ec 44     sub     esp, 68            ; 00000044H
081.00006 53       push    ebx
082.00007 56       push    esi
083.00008 57       push    edi
084.00009 8d 7d bc     lea     edi, DWORD PTR [ebp-68]
085.0000c b9 11 00 00 00   mov     ecx, 17            ; 00000011H
086.00011 b8 cc cc cc cc   mov     eax, -858993460        ; ccccccccH
087.00016 f3 ab        rep stosd
088. 
089.; 16   :  char * p =(char*)100;
090. 
091.00018 c7 45 fc 64 00
092.00 00        mov     DWORD PTR _p$[ebp], 100    ; 00000064H
093. 
094.; 17   :  *p=100;
095. 
096.0001f 8b 45 fc     mov     eax, DWORD PTR _p$[ebp]
097.00022 c6 00 64     mov     BYTE PTR [eax], 100    ; 00000064H
098. 
099.; 18   : }
100. 
101.00025 5f       pop     edi
102.00026 5e       pop     esi
103.00027 5b       pop     ebx
104.00028 8b e5        mov     esp, ebp
105.0002a 5d       pop     ebp
106.0002b c3       ret     0
107.?Crash1@@YAXXZ ENDP                 ; Crash1
108._TEXT   ENDS
109.END

其中

1.?Crash1@@YAXXZ PROC NEAR                ; Crash1, COMDAT

为Crash1汇编代码的起始行。产生崩溃的代码便在其后的某个位置。接下去的一行为:

1.; 15   : {

冒号后的"{"表示源文件中的语句,冒号前的"15"表示该语句在源文件中的行数。这之后显示该语句汇编后的偏移地址,二进制码,汇编代码。如

1.00000   55       push    ebp

其中"0000"表示相对于函数开始地址后的偏移,"55"为编译后的机器代码," push ebp"为汇编代码。从"cod"文件中我们可以看出,一条(c/c++)语句通常需要编译成数条汇编语句 。此外有些汇编语句太长则会分两行显示如:

1.00018   c7 45 fc 64 00
2.00 00        mov     DWORD PTR _p$[ebp], 100    ; 00000064H

其中"0018"表示相对偏移,在debug版本中,这个数据为相对于函数起始地址的偏移(此时每个函数第一条语句相对偏移为0000);release版本中为相对于代码段第一条语句的偏移(即代码段第一条语句相对偏移为0000,而以后的每个函数第一条语句相对偏移就不为0000了)。"c7 45 fc 64 00 00 00 "为编译后的机器代码 ,"mov DWORD PTR _p$[ebp], 100"为汇编代码, 汇编语言中";"后的内容为注释,所以";00000064H",是个注释这里用来说明100转换成16进制时为"00000064H"。

接下去,我们开始来定位产生崩溃的语句。

第一步,计算崩溃地址相对于崩溃函数的偏移,在本例中已经知道了崩溃语句的地址(0x00401082),和对应函数的起始地址(0x00401060),所以崩溃地址相对函数起始地址的偏移就很容易计算了:

1.崩溃偏移地址 = 崩溃语句地址 - 崩溃函数的起始地址 = 0x00401082 - 0x00401060 = 0x22。

第二步,计算出错的汇编语句在cod文件中的相对偏移。我们可以看到函数Crash1()在cod文件中的相对偏移地址为0000,则

1.崩溃语句在cod文件中的相对偏移 =  崩溃函数在cod文件中相对偏移 + 崩溃偏移地址 = 0x0000 + 0x22 = 0x22

第三步,我们看Crash1函数偏移0x22除的代码是什么?结果如下

1.00022  c6 00 64     mov     BYTE PTR [eax], 100    ; 00000064H

这句汇编语句表示将100这个数保存到寄存器eax所指的内存单元中去,保存空间大小为1个字节(byte)。程序正是执行这条命令时产生了崩溃,显然这里eax中的为一个非法地址 ,所以程序崩溃了!

第四步,再查看该汇编语句在其前面几行的其对应的源代码,结果如下:

1.; 17   :  *p=100;

其中17表示该语句位于源文件中第17行,而“*p=100;”这正是源文件中产生崩溃的语句。

至此我们仅从崩溃地址就查找出了造成崩溃的源代码语句和该语句所在源文件中的确切位置,甚至查找到了造成崩溃的编译后的确切汇编代码!

怎么样,是不是感觉更爽啊?

五、小节

1、新方法同样要注意可以适用的范围,即程序由一条语句当即引起的崩溃。另外我不知道除了VC6外,是否还有其他的编译器能够产生类似的"cod"文件。

2、我们可以通过比较 新方法产生的debug和releae版本的"cod"文件,查找那些仅release版本(或debug版本)有另一个版本没有的bug(或其他性状)。例如"罗文"中所举的那个用例 ,只要打开release版本的"cod"文件,就明白了为啥debug版本会产生崩溃而release版本却没有:原来release版本中产生崩溃的语句其实根本都没有编译 。同样本例中的release版本要看到崩溃的效果,需要将编译选项改为为不优化的配置。


一个示例:

1.设置

2.重新编译

3.定位

Delphi 通过Access Violation地址错误找到错误的哪行代码 什么是 MAP 文件?简单地讲, MAP 文件是程序的全局符号、源文件和代码行号信息的唯一的文本表示方法,它可以在任何地方、任何时候使用,不需要有额外的程序进行支持。而且,这是唯一能找出程序崩溃的地方的救星。 DELPHI下生成MAP文件的方法:生成详细的MAP信息的方法(二选一)1. project -> options -> Linker -> Map file ... 阅读详情

相关推荐

Versal - 从零构建Petalinux 2024.2 AI边缘计算平台(VD100+SDT+JupyterLab实战)

本文详细介绍了如何从零开始,基于AMD Versal VD100开发板和Petalinux 2024.2构建AI边缘计算平台。内容涵盖开发环境搭建、Petalinux工程创建与配置、SDT新流程实战、启动SD卡制作,并最终集成JupyterLab与Conda,打造出开箱即用的交互式AI开发环境,帮助开发者快速进行算法验证与部署。

5f4d3s2a1q的博客 489

调试Release发布版程序的Crash错误

原文:http://www.cppblog.com/woaidongmao/archive/2011/05/10/146092.html 把上述原文整理成一篇的地址:http://blog.sina.com.cn/s/blog_48f93b530100fsln.html 在Windows平台下用C++开发应用程序,最不想见到的情况恐怕就是程序崩溃,而要想解决引起问题的bug,最困难的应该就是调

yh880的专栏 1043

1、STVD和STVP的使用及串口烧写程序教程

文章目录一、前述二、STVD的使用三、STVP的使用1、STVP的作用:2、STVP的使用四、串口烧录程序 一、前述 STVD是意法半导体推出的,可以支持STM8和STM32 而IAR不尽如此,还支持51,MSP430等芯片 软件开发环境:编写程序,调试软件功能,下载固件到单片机中 硬件开发环境:连接外围电路,驱动功能外设,实现电气功能 最终构成一个以STM8系列单片机作为控制核心的应用系统。 MCS-51 一般的开发环境是 IAR 和 Keil STM8 一般的开发环境是 IAR 和 ST

Clichong 1万+

调试技巧 —— 如何利用windbg + dump + map分析程序异常

之前碰到论坛里有几个好友,说程序不时的崩溃,什么xxoo不能read的!  如果光要是这个内存地址,估计你会疯掉~~ 所以分享一下基本的调试技巧,需要准备的工具有WinDbg + VC6.0, 下面是自己整理的一份自动生成DUMP文件的源代码,只需要添加到工程即可,源代码如下: MiniDump.h MiniDump.cpp 1、在CXXDlg::OnIni

wangluozhangleilei的专栏 1万+

STM32 HAL库 实现基于SPI模式的SD卡、TF卡FATS文件系统+模拟U盘的应用笔记

很多单片机不带SDIO接口,所以在使用SD卡时必须使用SPI模式进行读写。 想做一个基于SPI的SD卡文件系统读写SD卡上的文件,再配合USB接口做一个模拟U盘。只能利用业余时间慢慢更新,也不知道能不能坚持下去。 我会把从零开始开发一个程序需要经历的过程一一的记录下来。做成一个奶妈级的单片机开发笔记。 一、硬件简介 1.SD卡和MicroSD卡(TF卡)的区别 由下图可以很容易的看出TF卡只是比SD卡少了一个3脚Vss脚,其它的管脚顺序

KyleKuang的博客 8334

从婴儿学步到工业级应用:VLA的‘隐式标定‘原理通俗图解

本文深入解析VLA(Vision-Language-Action)模型的'隐式标定'原理,通过类比婴儿学习机制,揭示其如何替代传统手眼标定技术。文章对比了工业机器人传统标定与VLA数据驱动方法的差异,并可视化神经网络注意力机制,展示其在空间关系编码上的突破性进展。最后探讨了VLA在工业应用中的优势与混合架构解决方案。

pz890123456的博客 324

VC下发布的Release版程序的异常捕捉

寻找Release版程发生异常退出的地方比Debug版麻烦得多。发生异常的时候windows通常会弹出一个错误对话框,点击详细信息,我们能获得出错的地址和大概的出错信息,然后可以用以下办法分析我们的程序。  一. 用MAP文件定位异常代码位置。1.如何生成map文件打开“Project →Project Settings”,选择 C/C++ 选项卡,在“Debug Info”栏选择

WLV的专栏 5706

beegfs源码分析

BeeGFS的客户端是由一个内核模块和两个系统服务组成的,这里咱们主要分析内核模块。由于BeeGFS的目录树解析,是在父目录DEntry里找子目录或文件DEntry,逐级迭代完成的,所以在Mount文件系统时,须要从管理节点获取根元数据节点的ID,而后再向根元数据节点查询根目录的DEntry的信息,为后续的目录解析打下基础。获取类似/data/beeond/data/dentries/38/51/root/#fSiDs#/文件fileId的父路径。1.1 FileID的生成。Session网络消息。

wfzy的博客 1913

[转]VC调试篇-不知道转自何处

shanshan VC调试篇 难怪很多前辈说调试是一个程序员最基本的技能,其重要性甚至超过学习一门语言。不会调试的程序员就意味着他即使会一门语言,却不能编制出任何好的软件。 我以前接触的程序大多是有比较成形的思路和方法,调试起来出的问题都比较小,最近这个是我自己慢慢摸索调试,接触了很多新的调试方法,并查了很多前辈的总结,受益匪浅,总结以前的和新的收获如下:...

weixin_30438813的博客 211

基于Python的京东商品价格监控与降价提醒系统设计与实现

本文详细介绍了如何使用Python构建一个完整的京东商品价格监控与降价提醒系统。系统通过爬虫技术实时抓取京东商品价格信息,结合数据存储与分析,实现价格波动监控和智能降价提醒功能。文章涵盖了系统设计、技术选型、代码实现以及部署方案,为电子商务价格监控领域提供了一个实用的解决方案。关键词:Python爬虫、京东API、价格监控、降价提醒、自动化。

2201_76125261的博客 405

【数据分析】R语言分段结构方程模型手把手教程(Piecewise Structural Equation Model)

分段结构方程模型(Piecewise Structural Equation Model, SEM)是一种用于分析变量之间因果关系的统计方法。它通过将复杂的因果关系分解为多个简单的线性模型来评估变量之间的直接和间接效应。与传统的结构方程模型(SEM)不同,分段结构方程模型不需要假设数据的多变量正态分布,因此在处理非正态数据时更为灵活。

专注生信领域 2650

使用MAP文件快速定位程序崩溃代码行

作为程序员,平时最担心见到的事情就是程序发生了崩溃,无论是指针越界还是非法操作,都将给我们的应用系统造成巨大的损失。但在一个大型系统的测试过程中,初期出现程序崩溃似乎成了不可避免的事。其实测试中出现程序崩溃并不可怕,反而是测试的成功。我们更为关心的是程序中的哪一行导致了系统崩溃,这样我们才能有针对性的进行改正。  在VC中,我们可以利用出现程序崩溃时VC的自动跳转,定位到出错代码行。但在大量的压力

助跑。。。。。。跳 1174

ESP32学习笔记03-日志打印

日志分为5个等级。

Car12 1415

利用MAP文件定位程序崩溃代码行

利用MAP文件定位程序崩溃代码行           对于程序员来说,最不希望见到的事情莫过于程序发生了崩溃。         无论是指针越界还是非法操作,都将给我们的应用系统造成巨大的损失。但在一个大型系统的测试过程 中,初期出现程序崩溃似乎成了不可避免的事。其实测试中出现程序崩溃并不可怕,反而是测试的成功。我们更为关心的是程序中的哪一行导致了系统崩溃,这样我 们才能有针对性的进行改正

痞子龙3D编程 1731

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

如何使用MAP文件找到程序崩溃的原因

如何使用MAP文件找到程序崩溃的原因<br />(转载)<br />如何使用MAP文件找到程序崩溃的原因<br />作者 Wouter Dhondt 翻译 冯亦成(fengyc@pset.suntec.net)<br /><br />[译 者] 在我们调试程序的时候,习惯于不停的Step in, Step in...可是如果我们发现Debug版的exe可以完全正常运行,而Release版却经常莫名其妙Crash。那该怎么办??没有关系,这篇文章就是 帮你解决这个问题的:) 当然,你如果希望全面提高你的Deb

466

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

MS-VC 使用MAP文件快速定位程序崩溃代码行

程序员,平时最担心见到的事情就是程序发生了崩溃,无论是指针越界还是非法操作,都将给我们的应用系统造成巨大的损失。但在一个大型系统的测试过程中,初期出现程序崩溃似乎成了不可避免的事。其实测试中出现程序崩溃并不可怕,反而是测试的成功。我们更为关心的是程序中的哪一行导致了系统崩溃,这样我们才能有针对性的进行改正。  在VC中,我们可以利用出现程序崩溃时VC的自动跳转,定位到出错代码行。但在大量的压力测试

若水的专栏 2525

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

vc调试:使用MAP文件快速定位程序崩溃代码行-zz

   作为程序员,平时最担心见到的事情就是程序发生了崩溃,无论是指针越界还是非法操作,都将给我们的应用系统 造成巨大的损失。但在一个大型系统的测试过程中,初期出现程序崩溃似乎成了不可避免的事。其实测试中出现程序崩溃并不可怕,反而是测试的成功。我们更为关 心的是程序中的哪一行导致了系统崩溃,这样我们才能有针对性的进行改正。  在VC中,我们可以利用出现程序崩溃时VC的自动跳转,定

yyyyyyy10的专栏 3436

利用MAP文件精确定位代码中出错的代码行

作为程序员,我们平时最担心见到的事情是什么?是内存泄漏?是界面不好看?……错啦!我相信我的看法是不会有人反对的——那就是,程序发生了崩溃!“该程序执行了非法操作,即将关闭。请与你的软件供应商联系。”,呵呵,这句 M$ 的“名言”,恐怕就是程序员最担心见到的东西了。有的时候,自己的程序在自己的机器上运行得好好的,但是到了别人的机器上就崩溃了;有时自己在编写和测试的过程中就莫名其妙地遇到了非法操作,但

亿言 6828

使用MAP文件快速定位程序崩溃代码行(转)

作为程序员,平时最担心见到的事情就是程序发生了崩溃,无论是指针越界还是非法操作,都将给我们的应用系统造成巨大的损失。但在一个大型系统的测试过程 中,初期出现程序崩溃似乎成了不可避免的事。其实测试中出现程序崩溃并不可怕,反而是测试的成功。我们更为关心的是程序中的哪一行导致了系统崩溃,这样我 们才能有针对性的进行改正。  在VC中,我们可以利用出现程序崩溃时VC的自动跳转,定位到出错代码行。但在大量的

zcainiao的专栏 622

使用MAP文件定位程序崩溃代码行

    作为程序员,平时最担心见到的事情就是程序发生了崩溃,无论是指针越界还是非法操作,都将给我们的应用系统造成巨大的损失。但在一个大型系统的测试过程中,初期出现程序崩溃似乎成了不可避免的事。其实测试中出现程序崩溃并不可怕,反而是测试的成功。测试中出现程序崩溃的时候我们更为关心的是程序中的哪一行导致了系统崩溃,这样我 们才能有针对性的进行改正。     在VC中,我们可以利用出现程序崩溃时VC的自动跳转,定位到出错代码行。但在大量的压力测试时,尤其是多线程测试时,同时出现几十个错,这时VC本身的出错跳转

Guix 678

如何通过崩溃地址找到出错的代码行

这是从“VC编程经验总结7”中转出来的 借花献佛——如何通过崩溃地址找到出错的代码行 作为程序员,我们平时最担心见到的事情是什么?是内存泄漏?是界面不好看?……错啦!我相信我的看法是不会有人反对的--那就是,程序发生了崩溃! “该程序执行了非法操作,即将关闭。请与你的软件供应商联系。”,呵呵,这句 M$ 的“名言”,恐怕就是程序员最担心见到的东西了。有的时候,自己的程序在自己的机器上运行得好好的,

土星·北海若 3898
上一篇: C++ 应用程序部署
下一篇: map 文件的使用(续)
htt9931
博客等级 码龄24年 43粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值