Board logo

Subject: 第三方代码JCL在D11下出现Exception时内存有漏 [Print This Page]

Author: niaoge    Time: 2007-8-12 11:09     Subject: 第三方代码JCL在D11下出现Exception时内存有漏

第三方代码JCL的JCLDebug.pas,在D11下出现Exception时内存有漏,而且很严重
建议用JCL最新版试试,
我已经用JCL1.100代码编译了cw,没出现编译不通过
有空我测测再看看
Author: niaoge    Time: 2007-8-13 09:40

CnLangUtils.pas
function GetLocaleDataW(ID: LCID; out Flag: DWORD): string;
//加一个 out  不然这里内存有异常,
//其实我也不知道为什么要加out ,兴好昨晚认真看了stanleyxu2005 的贴子http://bbs.cnpack.org/viewthread.php?tid=1712&extra=page%3D1还有点记得
//刚好今天用BoundsChecker测cw,这里出现内存异常,于是就想到昨天的贴子,果然,加了out之后就没有了异常了,stanleyxu2005 大虾一个
function GetLocaleDataA(ID: LCID; out Flag: DWORD): string;  
//同上加一个 out

CnWizClasses.pas
// if FIconHandle <> 0 then      //加判断也没有用
//    DestroyIcon(FIconHandle); //不要这个,IDE自动释放FIconHandle,所以加了DestroyIcon反而找不到地址
上面的改动之前,D11启动后,什么也不动,总内存使用是0.9-1G,改完之后是 0.8G左右,足足快差200M

接贴
CnAlignSizeWizard.pas 内
新建窗体时,BoundsChecker会报地址错误,由是多加以下判断,改完之后正常了
function TCnAlignSizeWizard.UpdateNonVisualComponent(
  FormEditor: IOTAFormEditor): Boolean;
var
  Component: IOTAComponent;
  aWinControl:TWinControl;
  aPointer: Pointer;
  procedure DoHideNonvisualComponent(WinControl: TWinControl);
  var
    H: HWND;
    aHandle:HWND;
  begin
    aHandle:=WinControl.Handle;
    if aHandle<>0 then  //多加判断,有异常
    begin
      H := GetWindow(aHandle, GW_CHILD);
      if H<>0 then //判断
      begin
        H := GetWindow(H, GW_HWNDLAST);
        while H <> 0 do
        begin
          if HWndIsNonvisualComponent(H) then
            if Active and HideNonVisual then
              ShowWindow(H, SW_HIDE)
            else
              ShowWindow(H, SW_SHOW);
          H := GetWindow(H, GW_HWNDPREV);
        end;
      end;
    end;
  end;
begin
  Result := False;
  if Assigned(FormEditor) then
  begin
    Component := FormEditor.GetRootComponent;
    if Assigned(Component) and Assigned(Component.GetComponentHandle) and
      (TObject(Component.GetComponentHandle) is TWinControl) then
    begin
      aPointer:=Component.GetComponentHandle;
      if aPointer<>nil then //判断
      begin
        aWinControl:=TWinControl(aPointer);
        if Assigned(aWinControl) then  //判断
        begin
          DoHideNonvisualComponent(aWinControl);
          Result := True;
        end;
      end;
    end;
  end;
end;
经过上面一系列的改动, 使用到现在,cw很正常了,BoundsChecker也没有报错

[ 本帖最后由 niaoge 于 2007-8-13 14:07 编辑 ]
Author: niaoge    Time: 2007-8-13 13:53

上面内容是用BoundsChecker测的,fastMM和AQ没测出来
Author: Passion    Time: 2007-8-13 14:32

加out的,理由不充分吧,参数是个DWORD,不是结构啊?
Author: niaoge    Time: 2007-8-13 15:05



QUOTE:
原帖由 Passion 于 2007-8-13 14:32 发表
加out的,理由不充分吧,参数是个DWORD,不是结构啊?

你下载一个BoundsChecker测一下,然后加上Out测一下,会不会dword类型也与string一样,也是一个地址加上引用次数,汇编俺不懂,你能不能用汇遍看看加与不加out 各是什么样子的
Author: Passion    Time: 2007-8-14 19:25

DWORD就是一个简单的4字节值,没有引用计数的说法。GetLocaleDataW这块参考的是VCL中的写法,应该不会有啥问题的,怕是BoundsChecker误报。
CnAlignSizeWizard.pas 中我参考niaoge的意见做了一些修改,希望有空帮我们重新看看有无此等问题。
Author: Passion    Time: 2007-8-14 23:53

CnWizClasses.pas
// if FIconHandle <> 0 then      //加判断也没有用
//    DestroyIcon(FIconHandle); //不要这个,IDE自动释放FIconHandle,所以加了DestroyIcon反而找不到地址

这个经过我和zjy讨论,觉得niaoge是对的,已经照此修改了。感谢niaoge嘿嘿。
Author: shenloqi    Time: 2007-8-15 10:20

DWORD是标准的一个双字大小的一块内存,不会引用计数和附加其他信息的。BoundsChecker有误报也是正常的,不过如果GetLocaleDataW和GetLocaleDataA这两个函数可能没有对传入的DWORD进行处理,而在此之前有没有对传入的DWORD初始化,倒是可能会有问题,此时使用out因为会给DWORD设初值可能就不会让BoundsChecker误报了,建议检查一下这两个函数是不是没有在所有路径对传入的参数设值,以及检查调用这个函数的地方是不是没有设初值。
Author: Passion    Time: 2007-8-15 12:20

检查了一下,这两个函数是做函数指针用的:

var
  GetLocaleDataProc: function (ID: LCID; Flag: DWORD): string;
begin
  if Win32Platform = VER_PLATFORM_WIN32_NT then
    GetLocaleDataProc := @GetLocaleDataW
  else
    GetLocaleDataProc := @GetLocaleDataA;

调用时:
GetLocaleDataProc(AID, LOCALE_SABBREVLANGNAME);

如果加了out,那么调用时传入的参数内容会被忽略,LOCALE_SABBREVLANGNAME又是常量,照理是不能以out的方式传入的。这样加out只会出错。
Author: shenloqi    Time: 2007-8-15 14:25

恩,我也看了一下这个函数,此处是不能加out的。感觉上这两个函数应该不会有什么问题。

BTW:
GetLocaleDataA函数中的SetString(Result, Buffer, GetLocaleInfoA(ID, Flag, Buffer, SizeOf(Buffer)) - 1);看GetLocalInfo的SDK文档,似乎不需要将返回值减一?
Author: shenloqi    Time: 2007-8-22 15:31

小海螺,你用BounderChecker说CnPack的TCnLanguages有问题是在什么环境下测到的?D2007吗?怎么测的?我看了一下代码TCnLanguages和TLanguages的代码是一模一样的,要出错应该大家都出错的啊,要不你试试看写一个程序使用Delphi自己的TLanguages看BounderChecker会不会报D2007的TLanguages也有问题?
Author: niaoge    Time: 2007-8-22 15:36

D2007




Welcome to CnPack Forum (http://bbs.cnpack.org/) Powered by Discuz! 5.0.0