对于按Release编译的程序,需要一些额外的工作才能找到产生错误的地方,下面描述了如何根据错误提示信息定位错误代码的过程:
设置WINCEMAP和WINCECOD两个环境变量,然后重新编译整个项目,我是在BAT文件中加入这两行代码:
set WINCEMAP=1
set WINCECOD=1
错误产生在s3c2440disp.dll内部,打开文本文件s3c2440disp.map(与s3c2440disp.dll在同一目录),在文件头中,"Preferred load address is 10000000"指出Rav地址为0x10000000,将其与错误产生的偏移地址0x00003660相加,得到Rva+Base地址为0x10003660(0x10000000 + 0x00003660)
在s3c2440disp.map文件中,根据Rva+Base地址,得知错误产生于s3c2440disp.obj中的S3C2440DISP::CursorOff成员函数内部
0001:00002274 ?CursorOn@S3C2440DISP@@QAAXXZ 10003274 f s3c2440disp.obj
0001:00002578 ?CursorOff@S3C2440DISP@@QAAXXZ 10003578 f s3c2440disp.obj
0001:000026f4 ?SetPointerShape@S3C2440DISP@@UAAJPAVGPESurf@@0HHHH@Z 100036f4 f s3c2440disp.obj
CursorOff函数起始地址为0x10003578,错误指令在代码中的偏移为0xE8 (0x10003660 - 0x10003578)
打开文件s3c2440disp.cod文件(与s3c2440disp.obj在同一目录),定位到CursorOff函数偏移0xE8处(0x10003660 - 0x10003578, 错误地址-函数开始地址),即可找到了错误发生的汇编代码和对应的C源代码
; 624 : {
; 625 : break;
; 626 : }
; 627 :
; 628 : ptrLine[x * (m_colorDepth >> 3)] = cbsLine[(x - m_CursorRect.left) * (m_colorDepth >> 3)];
000d0 e59430c0 ldr r3, [r4, #0xC0]
000d4 e59420e4 ldr r2, [r4, #0xE4]
000d8 e1a001a3 mov r0, r3, lsr #3
000dc e0463002 sub r3, r6, r2
000e0 e0227093 mla r2, r3, r0, r7
000e4 e021e690 mla r1, r0, r6, lr
000e8 e5d23000 ldrb r3, [r2]
000ec e5c13000 strb r3, [r1]
(错误行的汇编代码表明CPU在读入cbsLine指针指向的数据时发生了异常,经过调试,最终得知错误产生是因为某些情况下cbsLine指针无效而导致Data Abort异常)