请教怎样看 'Data Abort' 错误啊?

http://www.armce.com/bbs/thread-194-1-1.html

网上说  'Data Abort'  都是内存泄露引起的,后来去微软看CE内存泄露的视频,发现CE5的,回来找不到那个调试软件,发觉我白忙乎一场。


114087 PID:400002 TID:4db0016 Exception 'Data Abort' (4): Thread-Id=04db0016(pth=997cad5c), Proc-Id=00400002(pprc=824bf308) 'NK.EXE', VM-active=04c8000e(pprc=9954a560) 'iesample.exe'
114090 PID:400002 TID:4db0016 PC=c01cf8ec(gwes.dll+0x0004f8ec) RA=c01cf8e4(gwes.dll+0x0004f8e4) SP=d1e9fde0, BVA=00001002

好像是内存的配置问题,config.bib那里,你仔细看看是否改动了。

==============================================

主要就是看PC=c01cf8ec(gwes.dll+0x0004f8ec)这句话,你找偏移4f8ec,根据gwes.map找位于哪个function里面。然后参考gwes.pdb找到具体是哪行源码。

==============================================

我从你的map里面剪了一段,这段包含了0x0004f8ec的偏移。
从里面看,0x0004f88c<0x0004f8ec<0x0004f914
所以0x0004f8ec这个地址偏移肯定是0x0004f88c位置的function中间的代码段,对比发现这个地址在是SetFontSmoothing这个API里面。
所以使用map就可以定位function了。
第二步就是定位代码位置,我可能记错了,pdb格式是二进制的,有个叫做cod的格式才能看到具体在哪行代码出现了问题。

==============================================

SetFontSmoothing这个function可能没有暴露成为系统的GDI函数,可能其他GDI间接调用了,gwes一般本身不会代码有误,肯定是处理你传给它的指针的时候出现问题,你检查一下你所有的GDI操作的对象有没有问题。

==============================================

COD可能要修改MakeFile才能产生,你干脆加KITL然后看callstack算了。

==============================================

PC=c01cf8ec(gwes.dll+0x0004f8ec) 这个是关键
cod 可以在sources加上wincecod=1 吧,记得是。

==============================================

Walle老师您可能讲的有所错误,并非SetFontSmoothing这里。
这几天调试下了 可以确认 gwes.dll 的 TimerEntry 这里开始断点的
PC=c01cf8ec(gwes.dll+0x0004f8ec)的偏移量 就是 gwes.dll 的 Preferred load address is 10000000加上0x0004f8ec;
也就是
0001:0004e8c4       ?IsValidTimerEntry@TimerEntry_t@@QAA_NXZ 1004f8c4 f   gwes_lib:timer.obj
0001:0004e940       ?TimerQueuesRemoveSingleEvent@TimerEntry_t@@SAPAU1@PAUHWND__@@IPAVMsgQueue@@@Z 1004f940 f   gwes_lib:timer.obj
0001:0004ea38       ?
之间

从CEdubgeX的调试得知处理这个的线程是IE一个“NEW Window” 的线程

==============================================

这块我可能疏忽了一点,就是每个process的低0x1000是预留的,和ce5是一样的。
所以算法要先减去0x1000查表,所以是0x4e8ec去查map,结果就和你一致了。
谢谢你的提醒。
---------------
|                   |
| DataAbort   |    0x0004f8ec  -->   map里面的地址的0x0004e8ec
|                   |
| ------------ |    0x00001000  --> map里面的地址的0x000000000
| Reserved     |
------------ --    0x00000000
但是你这个是dll,不晓得是否也可以用这个方法来判断

==============================================

Windows CE: Finding the cause of a Data Abort


For Windows CE 5.0 and 6.0 looking up the instructions that caused the Data Abort is easier than in previous versions.  The module name and offset are included in the Data Abort output.  Take the following case:

Exception 'Data Abort' (4): Thread-Id=00df0002(pth=87e31c98), Proc-
Id=00400002(pprc=81118308) 'NK.EXE', VM-active=015f0002(pprc=87e07b70) 'udevice.exe'
PC=c098704c(usbfn.dll+0x0001704c) RA=c09880b0(usbfn.dll+0x000180b0) SP=d03ce2d8, BVA=00000000

This output gives us some valuable information including the module that failed and the offset into the module that the failure occurred.  For this one, the module is usbfn.dll and the module offset (MO) is 0x000180b0.  Skip ahead to number 3 below.


But if you are using Windows CE 4.2 or prior, then you will need to do some work to get the module name and offset.  I have found that using the RA value, in your case 02ea2614, as your Exception Address (EA) works best.

Look up EA in your makeimg output.  It falls between two modules code starts (CS).  The one with the lower number is the module with the problem.   In Platform Builder for Windows CE 4.x, the makeimg output is in the root folder of you project in <project name>.PLG.
Then the Module Offset (MO) is EA-CS=MO.  
For Windows CE 5.0 and later, MO = MO - 0x1000
Look MO up in <module.map> in your target folder.  Similar to looking it up in the makeimg output, it will give you the function that caused the exception, and the function offset (FO).
Now find the Instruction Offsett(IO) MO-FO=IO.  
Now figure out which c/c++ file contains the function, look up the function in the corresponding .COD file, and find IO.  That is the assembly instruction that caused the exception, look up a few lines an you will see the C code.

If you don't have the .COD files, set the environment variable WINCECOD=1
and rebuild.
============================================================
如何诊断Windows CE的应用程序崩溃
参看博客:
http://blog.csdn.net/singlerace/archive/2008/07/15/2655154.aspx
无论你是一个单纯的电脑用户还是一名高级软件工程师,都一定对程序崩溃不陌生。做为一名Windows CE应用程序开发者,你也一定遇到过下图这种场景:
这个对话框告诉你,有一个叫installer.exe的程序在地址00019320处崩溃了。如果这个程序归你负责,那么你的问题就来了:怎么找出这个BUG?这篇文章我想谈谈我在这方面的一些经验。
Windows CE的崩溃界面给出的信息十分的少,其中最有用的无疑是崩溃地址,如果你能从崩溃地址定位到源代码去,这个问题可以说就解决了一半。
从地址定位到源代码的方法有几种。一种是利用MAP文件:你可以在BUILD程序时生成MAP文件。MAP文件是一个文本文件,其中主要记录了各个函数入口对应的地址信息。比如这个例子中,崩溃地址对应的入口是:
0001:000082f4 ??1?$CComPtr@UIImage@@@ATL@@QAA@XZ 000192f4 f i ImageViewer.objMAP文件的好处是它是文本文件,可以人工阅读,缺点是信息不够多,只能定位到函数级别,而且要看懂MAP文件你需要有足够的经验,比如其中那串长长的貌似乱码的字符串是C++函数经过name mangling处理后的结果,没有一定的经验你根本没法还原出实际的函数。
另一种方法是利用PDB文件,PDB文件收集了应用程序的调试符号。PDB文件提供的信息很全,不过你得需要一定的工具才能解读它。如果你是一个经验丰富的Windows桌面平台的应用程序开发者,你可能听说过MSJ(Microsoft System Journal)这本杂志。如果你曾经看过这本杂志,应该对Bugslayer不陌生。在这篇文章中,Bugslayer介绍了他做的一个工具:CrashFinder。CrashFinder可以从崩溃地址通过查询相应的PDB文件直接定位到导致崩溃的源代码行。幸运的是,由于Windows CE可执行程序及其PDB文件的格式和Windows桌面系统上的是一样的,因此CrashFinder也可以用来定位Windows CE程序的崩溃地址。下面是CrashFinder显示的结果:

CrashFinder提供的信息十分有用,但是不够直观。为此我在Remote Process Explorer提供了一个更方便的界面,它可以直接显示源代码,并把导致崩溃的那一行highlight出来:
PDB文件里包含着大量的调试信息可以帮助你诊断应用程序错误,因此一般来说即使是正式release的版本,你也应该生成并维护好这些PDB文件。使用PDB文件的关键是崩溃的应用程序和PDB文件一定要匹配,否则它不但不能帮到你,反而会误导你。下图是VS2005中设置生成PDB文件和MAP文件的地方:
前面说过,Windows CE的崩溃界面给出的信息十分少,很多时候我们还需要更多的信息才能定位问题,另外有些Windows CE设备可能根本没有显示器。为解决这一问题,Windows CE在应用程序崩溃时还同时往外(一般是串口)输出相关的崩溃信息。比如这个例子中,如果你正好接着调试串口,开着HyperTerminal,那么在程序崩溃的时候你会看到这样的信息:
Data Abort: Thread=8d661000 Proc=81a477c0 &apos;installer.exe&apos;
AKY=00000401 PC=00019320(installer.exe+0x00009320) RA=00019094(installer.exe+0x0
0009094) BVA=16080100 FSR=00000007我相信Windows CE开发者一定也对这几行信息很熟悉。怎么利用这些信息诊断程序的问题?这里面最关键的信息是PC和RA给出的地址信息。PC就是上面提到的崩溃地址,根据这个地址用CrashFinder或者我的Remote Process Explorer里的Crack Address界面可以定位到导致崩溃的源代码行;RA是PC的返回地址(Return Address),根据这个地址可以找到导致崩溃的上一级函数,这个信息也很重要,因为很多时候崩溃的原因往往是上层函数往底层函数传递了非法参数导致的,比如你的应用程序用一个非法的窗口类调用MFC函数,崩溃地址在MFC函数里面,但是出问题的地方在你的调用代码里。下图是RA地址对应的源代码:
除了PC和RA,其他信息也可以提供一些参考作用:BVA是ARM中的Fault Address Register(FAR),是引起Data Abort的虚拟地址,比如说你的程序试图访问一个非法地址里的内容,那么Data Abort时BVA就是这个非法地址;FSR是Fault Status Register,指明导致异常的原因,FSR的解释可以看这里。要注意的是Thread和Proc给出的不是Thread Id/Thread Handle或者Process Id/Process Handle,它们给出的是该Thread或Proc对应的内核对象的指针,类似于Window NT平台的TEB和PEB的概念。由于你看到崩溃信息时线程已经退出了,因此根据这个信息在事后你无法知道是哪个线程出的错。以后我将介绍一种系统级的logging机制,这种机制可以把每条log的Thread Id、TEB等信息同时记录下来,这样在崩溃时就可以根据Data Abort的TEB信息和先前log中出现的TEB,找到出错的线程。这样,你不但可以定位到错误的源代码,还能找到运行错误代码的线程,将大大提高解决问题的效率。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/singlerace/archive/2008/07/15/2655154.aspx


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/dragonliabc/archive/2010/04/25/5527638.aspx

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值