AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

MemLeak, aber wo???

Ein Thema von snook · begonnen am 12. Mai 2011 · letzter Beitrag vom 14. Mai 2011
Antwort Antwort
snook

Registriert seit: 25. Jun 2010
94 Beiträge
 
Delphi 2005 Professional
 
#1

MemLeak, aber wo???

  Alt 12. Mai 2011, 10:46
FastMM4 zeigt mir in der proc UpdateInfoTable nen leak an, genaueres zur methode wird dann aber nciht mehr angezeigt

jedenfalls sind die ganzen zugirffe auf die IDataModule leckfrei. es kann eigentlich nur irgendwie mit den PChars zu tun haben. oder ich geb nen Item (PPlugInInfoTable) nicht richtig frei. hab jetzt aber schon solange draufgestarrt, dass ich nciht mehr durchblicke.

Delphi-Quellcode:

  PPlugInInfoTable = ^TPlugInInfoTable;
  TPlugInInfoTable = packed record
    Name, Dll,
    Date, Author: PChar;
    Status : TPlugInStatus;
    GUID : PChar;
    Handle : Cardinal;
    Version : real;
  end;

function CopyPChar(Source: PChar): PChar;
var dummy: ansistring;
begin
  result := nil;
{  if length(Source) > 0 then
    StrAlloc(result, StrLen(@Source[1]) + 1)
  else
    StrAlloc(result, 1);
  StrCopy(result, Source);}

  result := StrNew(Source);
end;

function StringToPchar(s: ansistring): PChar;
begin
  if length(s) > 0 then
    result := CopyPChar(@s[1])
  else
    result := CopyPChar(nil);
end;

procedure FreePChar(Ch: PChar);
begin
  StrDispose(Ch);
  Ch := nil;
end;

procedure NewInfoItem(out PItem);
begin
  new(PPlugInInfoTable(PItem));
  with(PPlugInInfoTable(PItem)^) do
  begin
    Name := nil;
    Dll := nil;
    Date := nil;
    Author:= nil;
    GUID := nil;
    Status:= psNil;
    Handle:= 0;
  end;
end;

procedure DisposeInfoItem(PItem: PPlugInInfoTable);
begin
  if Assigned(PItem^.Name) then FreePChar(PItem^.Name);
  if Assigned(PItem^.Dll) then FreePChar(PItem^.Dll);
  if Assigned(PItem^.Date) then FreePChar(PItem^.Date);
  if Assigned(PItem^.Author) then FreePChar(PItem^.Author);
  if Assigned(PItem^.GUID) then FreePChar(PItem^.GUID);
  dispose(PItem);
  PItem := nil;
end;

procedure TPlugInMain.UpdateInfoTable;
var LAdapter: IAdapter;
    LExtAdapter: IPlugInDllAdapter;
    DataTable, PlugInTable, Entry,
    AdapterModule, AdapterEntry: IDataModule;
    PlugIn : IPlugIn;
    PItem,
    PDummy : PPlugInInfoTable;
    i,lCount: integer;
    s : string;
begin
  while FInfoTableList.Count > 0 do
  begin
    PItem := FInfoTableList[0];
    disposeInfoItem(PItem);
    FInfoTableList.Delete(0);
  end;

  FData.GetDataTableLib(DataTable);
  if Assigned(DataTable) then
    try
      DataTable.GetFirstDataModule(Entry);
      while Assigned(Entry) do
        try
          NewInfoItem(PDummy);
          PDummy^.Name := copyPChar(Entry.GetCharValue(PChar('Name')));
          PDummy^.Dll := copyPChar(Entry.GetCharValue(PChar('DLLFile')));
          FData.GetPlugInLibrary(Entry.GetCharValue(PChar('DLLFile')),PlugInTable);
          if Assigned(PlugInTable) then
            try
              PDummy^.Date := StringToPChar(
                              DateToStr(PlugInTable.GetFloatValue(PChar('Date'))) + ' ' +
                              TimeToStr(PlugInTable.GetFloatValue(PChar('Date')))
                                           );
              GetDllAdapter(PlugInTable.GetIntValue(PChar('Handle')),LAdapter);
            finally
              PlugInTable := nil;
            end;
          if Assigned(LAdapter) then
            try
              if LAdapter.QueryInterface(IPlugInDllAdapter,LExtAdapter) = 0 then
                try
                  LExtAdapter.GetPlugInTable(AdapterModule);
                  if Assigned(AdapterModule) then
                    try
                      AdapterModule.GetDataModule(PDummy^.Name,AdapterEntry);
                    finally
                      AdapterModule := nil;
                    end;
                finally
                  LextAdapter := nil;
                end;
            finally
              LAdapter := nil;
            end;
          if Assigned(AdapterEntry) then
            try
              PDummy^.Author := CopyPChar(AdapterEntry.GetCharValue(PChar('Author')));
              PDummy^.GUID := CopyPChar(AdapterEntry.GetCharValue(PChar('GUID')));
              PDummy^.Version:= AdapterEntry.GetFloatValue(PChar('Version'));
            finally
              AdapterEntry := nil;
            end;
          FData.GetPlugInLibraryTable(Entry.Name,lCount,PlugInTable);
          if Assigned(PlugInTable) then
            try
              for i := 0 to lCount - 1 do
              begin
                NewInfoItem(PItem);
                if lCount = 1 then
                  Pitem^.Name := CopyPChar(PDummy^.Name)
                else
                begin
                  s := PDummy^.Name;
                  Pitem^.Name := StringToPChar(s + '('+IntToStr(i)+')');
                end;
                Pitem^.Dll := CopyPChar(PDummy^.Dll);
                PItem^.Author := CopyPChar(PDummy^.Author);
                PItem^.GUID := CopyPChar(PDummy^.GUID);
                PItem^.Date := copyPChar(PDummy^.Date);
                PItem^.Version:= PDummy^.Version;
                FData.GetPlugIn(StrToInt(Entry.Name),i,PlugIn);
                if Assigned(PlugIn) then
                  try
                    PItem^.Handle := PLugIn.MsgHandle;
                    PItem^.Status := TPlugInStatus(IntToOrd(
                      SendMessage(PlugIn.MsgHandle,PM_QUERYSTATUS,MsgHandle,0)));
                  finally
                    PlugIn := nil;
                  end;
                FInfoTableList.Add(PItem);
              end;
              if Assigned(PItem) then
              begin
                PItem := nil;
                DisposeInfoItem(PDummy);
              end
              else
                FInfoTableList.Add(PDummy);
            finally
              PlugInTable := nil;
            end;
        finally
          DataTable.GetNextDataModule(Entry);
        end;
    finally
      DataTable := nil;
    end;
end;
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#2

AW: MemLeak, aber wo???

  Alt 12. Mai 2011, 11:07
Kann es sein das .GetCharValue Speicher anfordert für den PChar den du da zurück bekommst?
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
snook

Registriert seit: 25. Jun 2010
94 Beiträge
 
Delphi 2005 Professional
 
#3

AW: MemLeak, aber wo???

  Alt 12. Mai 2011, 11:19
eigentlich nicht oder?

Delphi-Quellcode:

function TCustomDataModule.GetCharValue(AKey: PChar): PChar;
var index: integer;
begin
  result := PChar('');
  index := IndexOf(AKey);
  with FList.LockList do
    try
      if (index > -1) and
         (PDataModuleItem(Items[index])^.datatype = STR_DATA) then
          result := PChar(PDataModuleItem(Items[index])^.Value);
    finally
      FList.UnlockList;
    end;
end;
mir fiel gerade noch ein, dass es evtl möglich ist, dass die PChars bei nem new(PItem) evtl vorinitialisiert werden mit irgend nem wert? so ala fillchar?
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#4

AW: MemLeak, aber wo???

  Alt 12. Mai 2011, 11:59
die werden maximal mit 0 initialisiert. Aber speicher verbraucht das nicht (es wird ja nur der Pointer gesetzt aber kein Speicher angefordert)

Wenn du wirklich denkst es liegt an den PChars, dann zähle doch einfach mal wie oft du mit CopyPChar und StringToPchar speicher anforderst und ob du genau so oft den Speicher mit FreePChar frei gibst.

Oder wird dir die Funktion nur angezeigt weil der Speicher der beim letzten Aufruf angefordert wurde nirgends mehr frei gegeben wird beim beenden des Programms?
1. Durchlauf: keinen Speicher freigeben, neuen Speicher(x1) für PChars etc. anfordern
2. Durchlauf: Speicher(x1) freigeben, neuen Speicher(x2) für PChars etc. anfordern
Programmende: Speicher(x2) wurde noch nicht frei gegeben?
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
snook

Registriert seit: 25. Jun 2010
94 Beiträge
 
Delphi 2005 Professional
 
#5

AW: MemLeak, aber wo???

  Alt 14. Mai 2011, 14:36
soo dank dir für die hilfe, hab mich da jetzt durchgekämpft und das leak gefunden. es war in einer dll. beim aufruf der methode LExtAdapter.GetPlugInTable . da würde mich mal interssieren ob fastmm4 deswegen nicht die methode angezeigt hat. kann es sein daa man dlls nicht untesuchen kann? hab mich an das dll-tutorial im fastmm4 gehalten.
  Mit Zitat antworten Zitat
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#6

AW: MemLeak, aber wo???

  Alt 14. Mai 2011, 15:23
kann es sein das man dlls nicht untesuchen kann?
Hast du die DLL denn mit Debug-Informationen kompiliert?
  Mit Zitat antworten Zitat
snook

Registriert seit: 25. Jun 2010
94 Beiträge
 
Delphi 2005 Professional
 
#7

AW: MemLeak, aber wo???

  Alt 14. Mai 2011, 16:43
einstellungen sind auf dem screenshot.
bin noch icht so ganz drin in fastmm
Miniaturansicht angehängter Grafiken
unbenannt.jpg  
  Mit Zitat antworten Zitat
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#8

AW: MemLeak, aber wo???

  Alt 14. Mai 2011, 17:19
einstellungen sind auf dem screenshot.
bin noch icht so ganz drin in fastmm
Das hat mit FastMM nichts zu tun.

Die Einstellung ist unter "Linker" zu finden (TD32-Debug-Info), danach Projekt->Projekt erzeugen aufrufen.
  Mit Zitat antworten Zitat
snook

Registriert seit: 25. Jun 2010
94 Beiträge
 
Delphi 2005 Professional
 
#9

AW: MemLeak, aber wo???

  Alt 14. Mai 2011, 19:52
ja nee das meinte ich nciht. wollte damit zum ausdruck bringen, dass ich nicht genau weiß welche einstellungen nötig sind, damit fastmm z.b. auch dll's debugged, bzw. die maximal möglichen infos rausgezogen werden können
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:06 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz