Конференция "KOL" » KOL 3.23 [Delphi, Windows]
 
  • Vladimir Kladov © (22.02.15 20:12) [20]
    Вот здесь полезная информация:
    Текущий дамп памяти из 256 байт начиная с адреса 7EF43120:



    Запускаем программу (F8), в Watches добавляем PDWORD($7EF43120), ставим "Break when changed", и каждый раз, когда первые 4 байта меняются, будет останов. Тут можно посмотреть, кто выделил.

    Вообще похоже на то, что было добавление в TList, сам TList никто не освободил.
  • Vladimir Kladov © (22.02.15 20:18) [21]
    Фреймы даже не буду сейчас смотреть, уже просто не помню, что там и как.

    Я вообще не вижу проблемы с утечками памяти. Если не мегабайтами течет. В современных приложениях вообще всё течет. Вин-8 - это просто одна сплошная протечка. Проги на шарпах со сборщиками мусора - там вообще не поймешь, то ли они текут беспрерывно, то ли это стратегия такая - мусор собирать раз в сутки.

    Вот утечки ресурсов - это серьезно. Можно винду завалить, даже и 7-ку. 8-ку не пробовал (мало я с ней работал), но почему-то есть подозрение, что там ничего не изменилось.
  • QAZ (22.02.15 20:26) [22]

    > Проги на шарпах

    тык если во всех книгах для батонокидателей пишут про наличие сборщика и необязательность высвобождения, то фигли им мучится...

    для меня утечка это как минимум сигнал что что то не так, а если что то не так, то в итоге накопится куча неразгребешь
    вот с меню разобрались, сразу стали видны "скрытые" им другие проблемы

    про фреймы хотяб скажи правильно ли им так назначать "родителя" и как их освобождать, просто фри или еще чего надо?
  • QAZ (22.02.15 20:42) [23]

    > [+] Метод TBitmap.CopyToClipboard переименован в CopyToClipboardAsDIB,
    >  добавлена другая версия CopyToClipboard, использующая формат
    > CF_BITMAP (существенно более короткий код).

    и пока я шарю в клипбордах :)
    CopyToClipboardAsDIB - вообще нафиг не нужна
    CF_DIB, CF_DIBV5 и CF_BITMAP взаимно конвертируются самой виндой при запросе конкретного варианта, а в 8ке вся эта метрошная лабуда вообще только CF_BITMAP должна посылать в буфер
  • Vladimir Kladov © (22.02.15 21:17) [24]

    > правильно ли им так назначать "родителя" и как их освобождать

    Я сейчас точно уже не скажу как. В свете сегодняшних рытьёв наверное правильно сказать MyFrame.Form.Close; И да, я знаю, что это не форма, а, в общем-то, панель. Просто отправляется WM_CLOSE, дальше все по свистку от винды.


    > CopyToClipboardAsDIB - вообще нафиг не нужна

    Пусть останется. Я работал с битмапами, которые бывают только в DIB'е, потому что handle винде выделить не получается, слишком большой. И для совместимости.
  • Thaddy © (23.02.15 17:34) [25]
    I've merged 3.23++ into 64 bit unofficial. Plz test.
    Link is:
    http://thaddy.org/kol323-x64-unofficial.7z
  • Thaddy © (23.02.15 17:47) [26]
    This also contains function format for Freepascal and updated koldef.inc for Freepascal 3.0.1/3.1.1
  • Vladimir Kladov © (24.02.15 11:09) [27]

    > merged 3.23++

    too fast. An error in asm version of run. it should be:

    procedure Run( var AppletCtl: PControl );
    asm
    //----- if  AppletCtl = nil then Exit;
           TEST      EAX, EAX
           JZ        @@exit
           PUSH      EBX
           XCHG      EBX, EAX

    //----- AppletRunning := TRUE;
           INC       [AppletRunning]

    //----- Applet := AppletCtl;
           MOV       EAX, [EBX]
           MOV       [Applet], EAX

    //----- AppletCtl.CreateWindow;
           CALL      CallTControlCreateWindow

    //----- WHILE NOT AppletTerminated DO
    @@loop: CMP       [AppletTerminated], 0
           JNZ       @@end_loop

    //----- WaitMessage;
           CALL      WaitMessage

    //----- AppletCtl.ProcessMessages;
           MOV       EAX, [EBX]
           CALL      TControl.ProcessMessages

           {$IFDEF   USE_OnIdle}
    //----- ProcessIdle(AppletCtl);
           MOV       EAX, [EBX]
           CALL      [ProcessIdle]
           {$ENDIF}

           JMP       @@loop
    @@end_loop:

           {$IFDEF LET_MENU_LEAK}
           MOV       ECX, [EBX]
           XCHG      EAX, EBX
           POP       EBX
           JECXZ     @@exit
           {$ELSE}
           POP       EBX
           LEA       EAX, [Applet]
           CMP       [EAX], 0
           JZ        @@exit
           {$ENDIF}
           CALL      TerminateExecution
    @@exit:
    end;

  • Vladimir Kladov © (24.02.15 11:09) [27]

    > merged 3.23++

    too fast. An error in asm version of run. it should be:

    procedure Run( var AppletCtl: PControl );
    asm
    //----- if  AppletCtl = nil then Exit;
           TEST      EAX, EAX
           JZ        @@exit
           PUSH      EBX
           XCHG      EBX, EAX

    //----- AppletRunning := TRUE;
           INC       [AppletRunning]

    //----- Applet := AppletCtl;
           MOV       EAX, [EBX]
           MOV       [Applet], EAX

    //----- AppletCtl.CreateWindow;
           CALL      CallTControlCreateWindow

    //----- WHILE NOT AppletTerminated DO
    @@loop: CMP       [AppletTerminated], 0
           JNZ       @@end_loop

    //----- WaitMessage;
           CALL      WaitMessage

    //----- AppletCtl.ProcessMessages;
           MOV       EAX, [EBX]
           CALL      TControl.ProcessMessages

           {$IFDEF   USE_OnIdle}
    //----- ProcessIdle(AppletCtl);
           MOV       EAX, [EBX]
           CALL      [ProcessIdle]
           {$ENDIF}

           JMP       @@loop
    @@end_loop:

           {$IFDEF LET_MENU_LEAK}
           MOV       ECX, [EBX]
           XCHG      EAX, EBX
           POP       EBX
           JECXZ     @@exit
           {$ELSE}
           POP       EBX
           LEA       EAX, [Applet]
           CMP       [EAX], 0
           JZ        @@exit
           {$ENDIF}
           CALL      TerminateExecution
    @@exit:
    end;

  • QAZ (24.02.15 11:20) [28]

    >  Но исправление слишком радикальное, меняется порядок уничтожения
    > окон. Может вылезти что угодно. Поэтому все можно будет
    > вернуть по заклинанию LET_MENU_LEAK.

    в общем печаль-тоска подобралась незаметно, есть новый виновник утечек и вылетов ---- KOLApplet
    обнаружил при попытке разборок с фреймами, мысль была что может без него им плохо живется, ну типа по аналогии с несколькими формами
    ток положил на форму и хобана + еще 8 утечек

    потом
    1)беру болванку эксперимента с меню, что выкладывал здесь, для приличия добавил 2ю форму, без апплета, запустил\закрыл - чисто
    2) кладу аплет, запустил\закрыл - стоп в CPU-окне отладчика на user32.DestroyWindow
    3) думаю, предупреждал же...
    4) ставлю дефин LET_MENU_LEAK, удалил меню, для чистоты эксперимента, запустил\закрыл - 9 утечек, включая те самые Тлисты....
    5) убираю аплетт, , запустил\закрыл - портянка на весь экран ошибка памяти
    6) убираю дефин LET_MENU_LEAK, запустил\закрыл - чисто

    кино ннада?
  • QAZ (24.02.15 11:20) [28]

    >  Но исправление слишком радикальное, меняется порядок уничтожения
    > окон. Может вылезти что угодно. Поэтому все можно будет
    > вернуть по заклинанию LET_MENU_LEAK.

    в общем печаль-тоска подобралась незаметно, есть новый виновник утечек и вылетов ---- KOLApplet
    обнаружил при попытке разборок с фреймами, мысль была что может без него им плохо живется, ну типа по аналогии с несколькими формами
    ток положил на форму и хобана + еще 8 утечек

    потом
    1)беру болванку эксперимента с меню, что выкладывал здесь, для приличия добавил 2ю форму, без апплета, запустил\закрыл - чисто
    2) кладу аплет, запустил\закрыл - стоп в CPU-окне отладчика на user32.DestroyWindow
    3) думаю, предупреждал же...
    4) ставлю дефин LET_MENU_LEAK, удалил меню, для чистоты эксперимента, запустил\закрыл - 9 утечек, включая те самые Тлисты....
    5) убираю аплетт, , запустил\закрыл - портянка на весь экран ошибка памяти
    6) убираю дефин LET_MENU_LEAK, запустил\закрыл - чисто

    кино ннада?
  • QAZ (24.02.15 11:26) [29]

    > беру болванку эксперимента с меню

    с дефином PAS_VERSION, чудеса не менее интересные, включая "рунтаймеррор"
  • QAZ (24.02.15 11:26) [29]

    > беру болванку эксперимента с меню

    с дефином PAS_VERSION, чудеса не менее интересные, включая "рунтаймеррор"
  • Thaddy © (24.02.15 12:31) [30]
    Package is now updated as per Vladimir's change. (kol_asm.inc)
  • Thaddy © (24.02.15 12:31) [30]
    Package is now updated as per Vladimir's change. (kol_asm.inc)
  • Vladimir Kladov © (24.02.15 13:08) [31]
    Вот где ошибка:

    procedure TerminateExecution( var AppletCtl: PControl );
    var App: PControl;
       Appalreadyterminated: Boolean;
    begin
     Appalreadyterminated := AppletTerminated;
     AppletTerminated := TRUE;
     AppletRunning := FALSE;
     App := Applet;
     Applet := nil;
     if (App <> nil) {and (App.RefCount >= 0)} then
     begin
       {$IFDEF LET_MENU_LEAK} //was IFNDEF !!!
       App.RefInc;
       {$ENDIF}
       if not Appalreadyterminated then
       begin
         App.ProcessMessages;
         App.Perform( WM_CLOSE, 0, 0 );
       end;
       AppletCtl := nil;
       {$IFNDEF LET_MENU_LEAK}            //   версия KOL 3.23+:
               DestroyWindow(App.Handle); //** В этом варианте вызывается не деструктор
       {$ELSE}                            //   объекта, а функция закрытия окна. Вызов
               App.Free;
               App.RefDec;                //   деструктора выполнится в обработчике
       {$ENDIF}                           //   события WM_DESTROY. В результате, сначала
     end;                                 //   успешно разрушится меню формы. 22.02.2015
    end;


    и вот тут, соответственно (kol_asm.inc, + перенос кода за скобки ifdef'а, так что лучше всю процедуру заменить):
    procedure TerminateExecution( var AppletCtl: PControl );
    asm
             PUSH EBX
             PUSH ESI
             MOV  BX, $0100
             XCHG BX, word ptr [AppletRunning]
             XOR  ECX, ECX
             XCHG ECX, [Applet]
             JECXZ @@exit

             PUSH EAX

             {$IFDEF LET_MENU_LEAK} // Was IFNDEF !!!
             XCHG EAX, ECX
             MOV  ESI, EAX
             CALL TObj.RefInc
             {$ENDIF}

             TEST BH, BH
             JNZ  @@closed

             MOV  EAX, ESI
             CALL TControl.ProcessMessages
             PUSH 0
             PUSH 0
             PUSH WM_CLOSE
             PUSH ESI
             CALL TControl.Perform
    @@closed:
             POP  EAX
             XOR  ECX, ECX
             MOV  dword ptr [EAX], ECX
             {$IFDEF LET_MENU_LEAK}
                  MOV  EAX, ESI
                  CALL TObj.RefDec
                  XCHG EAX, ESI
                  CALL TObj.RefDec
             {$ELSE}
                  PUSH [ESI].TControl.FHandle
                  CALL Windows.DestroyWindow
             {$ENDIF}
    @@exit:
             POP  ESI
             POP  EBX
    end;

  • Vladimir Kladov © (24.02.15 13:08) [31]
    Вот где ошибка:

    procedure TerminateExecution( var AppletCtl: PControl );
    var App: PControl;
       Appalreadyterminated: Boolean;
    begin
     Appalreadyterminated := AppletTerminated;
     AppletTerminated := TRUE;
     AppletRunning := FALSE;
     App := Applet;
     Applet := nil;
     if (App <> nil) {and (App.RefCount >= 0)} then
     begin
       {$IFDEF LET_MENU_LEAK} //was IFNDEF !!!
       App.RefInc;
       {$ENDIF}
       if not Appalreadyterminated then
       begin
         App.ProcessMessages;
         App.Perform( WM_CLOSE, 0, 0 );
       end;
       AppletCtl := nil;
       {$IFNDEF LET_MENU_LEAK}            //   версия KOL 3.23+:
               DestroyWindow(App.Handle); //** В этом варианте вызывается не деструктор
       {$ELSE}                            //   объекта, а функция закрытия окна. Вызов
               App.Free;
               App.RefDec;                //   деструктора выполнится в обработчике
       {$ENDIF}                           //   события WM_DESTROY. В результате, сначала
     end;                                 //   успешно разрушится меню формы. 22.02.2015
    end;


    и вот тут, соответственно (kol_asm.inc, + перенос кода за скобки ifdef'а, так что лучше всю процедуру заменить):
    procedure TerminateExecution( var AppletCtl: PControl );
    asm
             PUSH EBX
             PUSH ESI
             MOV  BX, $0100
             XCHG BX, word ptr [AppletRunning]
             XOR  ECX, ECX
             XCHG ECX, [Applet]
             JECXZ @@exit

             PUSH EAX

             {$IFDEF LET_MENU_LEAK} // Was IFNDEF !!!
             XCHG EAX, ECX
             MOV  ESI, EAX
             CALL TObj.RefInc
             {$ENDIF}

             TEST BH, BH
             JNZ  @@closed

             MOV  EAX, ESI
             CALL TControl.ProcessMessages
             PUSH 0
             PUSH 0
             PUSH WM_CLOSE
             PUSH ESI
             CALL TControl.Perform
    @@closed:
             POP  EAX
             XOR  ECX, ECX
             MOV  dword ptr [EAX], ECX
             {$IFDEF LET_MENU_LEAK}
                  MOV  EAX, ESI
                  CALL TObj.RefDec
                  XCHG EAX, ESI
                  CALL TObj.RefDec
             {$ELSE}
                  PUSH [ESI].TControl.FHandle
                  CALL Windows.DestroyWindow
             {$ENDIF}
    @@exit:
             POP  ESI
             POP  EBX
    end;

  • Vladimir Kladov © (24.02.15 13:10) [32]

    > Package is now updated as per Vladimir's change. (kol_asm.
    > inc)

    Thaddy, you are still too fast! :)
  • Vladimir Kladov © (24.02.15 13:10) [32]

    > Package is now updated as per Vladimir's change. (kol_asm.
    > inc)

    Thaddy, you are still too fast! :)
  • QAZ (24.02.15 15:41) [33]

    > Vladimir Kladov ©   (24.02.15 13:08) [31]

    да-да по крайней мере паскальный вариант, самый большой проект, где был Tlist в логе - это и было изза апплета, сейчас все чисто

    остался только косяк с фреймами (или табами) в другом

    > Запускаем программу (F8), в Watches добавляем PDWORD($7EF43120),
    >  ставим "Break when changed", и каждый раз, когда первые
    > 4 байта меняются, будет останов. Тут можно посмотреть, кто
    > выделил.

    чет в 7ке нет такого "Break when changed" и пролетает мимо ненаходит
 
Конференция "KOL" » KOL 3.23 [Delphi, Windows]
Есть новые Нет новых   [118488   +59][b:0][p:0.005]