现在的位置: 首页 > 综合 > 正文

事实又一次证明,编译EXE程序时生成MAP文件是很有必要的

2013年10月17日 ⁄ 综合 ⁄ 共 1101字 ⁄ 字号 评论关闭

我一般会在给用户发新版本的同时生成MAP文件,并在自己机器上存起来备用。当系统遇见地址错误,尤其是崩溃时,MAP文件还是很有用的,让我们不致于不知所措。我通过MAP文件和错误地址已经不只一次找到出错代码。今天刚好又遇见了一个,在此记录下。

 

首先是程序用户那边出了错,错误主要有两个,日志输出如下:

2011-04-08 15:40:25 /600 [73][127.0.0.1:1227]用户请求出错 - X: 存取地址 00593676 违例发生在模块 'app.exe' 中. 读 在地址 00000008 里

2011-04-08 15:50:12 /600 [75][127.0.0.1:1256]用户请求出错 - X: 存取地址 005977EC 违例发生在模块 'app.exe' 中. 读 在地址 00000000 里

 

由于我的EXE入口地址是00401000,因此要把出错地址减去00401000:

005977EC-00401000=001967EC

00593676-00401000=00192676

故出错地址其实是:001967EC和00192676

 

这个程序是去年1月份编译的了,幸好我还有这个版本的MAP文件,打开来查了下这两个地址相近的值(就是用记事本打开,查找001967和001926,后面两位不精确所以不加入查找):

 

Line numbers for uQuerySvc(uQuerySS.pas) segment .text

   339 0001:0019266D   340 0001:00192683

 

0001:00196780       TQuerySSS.CreateNewQuery

0001:001973E0       TQuerySSS.DoAppHint

 

很显然,问题一出在uQuerSS.pas的第339行附近,问题二则出在TQuerySSS.CreateNewQuery这个函数里,分别找来看了下:

一、uQuerySS.pas Line339:

    for I := 0 to Count - 1 do

      if TComponent(Items[I]).Name = AName then

显然这里Items[I]为空没有做检测。
二、TQuerySSS.CreateNewQuery:
function TQuerySSS.CreateNewQuery(
  AName: string): TCustQuery;
begin
  Result := PoolList.AcquireQuery;
  with Result do
  ...
显然这里Result也是为空没检测。
问题找到了,接下来就容易分析处理了。
在我这个例子中,其实这是个已知并已解决的BUG,只是用户的版本太旧,换了个新版本就OK了。
【上篇】
【下篇】

抱歉!评论已关闭.