AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Kann das Speicherleck nicht finden...
Thema durchsuchen
Ansicht
Themen-Optionen

Kann das Speicherleck nicht finden...

Ein Thema von BenTech · begonnen am 22. Dez 2005 · letzter Beitrag vom 30. Dez 2005
Antwort Antwort
BenTech

Registriert seit: 16. Jun 2003
Ort: Dortmund
60 Beiträge
 
Turbo Delphi für Win32
 
#1

Kann das Speicherleck nicht finden...

  Alt 22. Dez 2005, 20:28
Hallo,
ich habe ein Programm geschrieben, das IPs anpingt. Für jeden Ping wird ein Thread erstellt. Ich stelle jedoch fest, dass bei jeder Threaderstellung und Terminierung 16 kByte verloren gehen.
Ich kann jedoch nicht nachvollziehen, wo das Speicherleck ist.

Hier der Aufruf des Threads...
Delphi-Quellcode:
IpWatchList[nowIPIndex].IPThread := TMyThreads.Create(true);
IpWatchList[nowIPIndex].IPThread.InetAddress := png_IP;
IpWatchList[nowIPIndex].IPThread.TimeOut := settings.TimeOut;
IpWatchList[nowIPIndex].IPThread.Index := nowIPIndex;
IpWatchList[nowIPIndex].IPThread.Resume;
So wird der Thread dann geschlossen...
Delphi-Quellcode:
procedure TForm1.UpdateIPView(Online : Boolean; Index : Integer);
begin
  //IpWatchList[Index].IPThread.FreeOnTerminate := true;
  IpWatchList[Index].IPThread.Terminate;
  if Online then
  begin
   //...
  end
  else
  begin
   //...
  end;
end;
Nach Terminate wird auch Speicher freigegeben. Jedoch weniger als zuvor reserviert wurde.

Im Thread geschieht folgendes...
Delphi-Quellcode:
procedure TMyThreads.Execute;
begin
  Online := Ping(InetAddress,TimeOut);
  UpdateMain;
end;

function TMyThreads.Ping(IPAddress : string; IPTimeOut : Integer) : boolean;
var
 Handle : THandle;
 InAddr : IPAddr;
 DW : DWORD;
 rep : array[1..128] of byte;
begin
  Result := false;
  Handle := IcmpCreateFile;
  if Handle = INVALID_HANDLE_VALUE then
   Exit;
  TranslateStringToTInAddr(InetAddress, InAddr);
  DW := IcmpSendEcho(Handle, InAddr, nil, 0, nil, @rep, 128, TimeOut);
  Result := (DW <> 0);
  IcmpCloseHandle(Handle);
end;

procedure TMyThreads.UpdateMain;
begin
  Form1.UpdateIPView(Online,Index);
end;
Zum Pingen benutze ich die Unit "raw_ping".
Vielen Dank schonmal für eure Hilfe .
Angehängte Dateien
Dateityp: pas raw_ping_125.pas (2,7 KB, 11x aufgerufen)
  Mit Zitat antworten Zitat
BenTech

Registriert seit: 16. Jun 2003
Ort: Dortmund
60 Beiträge
 
Turbo Delphi für Win32
 
#2

Re: Kann das Speicherleck nicht finden...

  Alt 23. Dez 2005, 00:53
Soo, habe das Leck jetzt einschränken können. Es befindet sich eindeutig in der Ping-Funktion. Wenn ich diese aus dem Programm entferne, verschwindet das Leck.

Also scheint hier irgendwo in der "raw_ping.pas" etwas nicht ganz sauber freigegeben zu werden...
Delphi-Quellcode:
function Ping(InetAddress : string; TimeOut : Integer) : boolean;
var
 Handle : THandle;
 InAddr : IPAddr;
 DW : DWORD;
 rep : array[1..128] of byte;
begin
  result := false;
  Handle := IcmpCreateFile;
  if Handle = INVALID_HANDLE_VALUE then
   Exit;
  TranslateStringToTInAddr(InetAddress, InAddr);
  DW := IcmpSendEcho(Handle, InAddr, nil, 0, nil, @rep, 128, 0);
  Result := (DW <> 0);
  IcmpCloseHandle(Handle);
end;
Die Unit enthält natürlich noch ein paar andere Funktionen, in denen sich das Leck befinden könnte.
Ich hoffe, ich befinde mich jetzt nicht auf der falschen Fährte . Über Hinweise würde ich mich sehr freuen
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.116 Beiträge
 
Delphi 11 Alexandria
 
#3

Re: Kann das Speicherleck nicht finden...

  Alt 23. Dez 2005, 11:19
Moin BenTech,

wie sieht denn TranslateStringToTInAddr aus?
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
BenTech

Registriert seit: 16. Jun 2003
Ort: Dortmund
60 Beiträge
 
Turbo Delphi für Win32
 
#4

Re: Kann das Speicherleck nicht finden...

  Alt 23. Dez 2005, 16:58
Hi,
hier die Prozedur...

Delphi-Quellcode:
procedure TranslateStringToTInAddr(AIP: string; var AInAddr);
var
  phe: PHostEnt;
  pac: PChar;
  GInitData: TWSAData;
begin
  WSAStartup($101, GInitData);
  try
    phe := GetHostByName(PChar(AIP));
    if Assigned(phe) then
    begin
      pac := phe^.h_addr_list^;
      if Assigned(pac) then
      begin
        with TIPAddr(AInAddr).S_un_b do begin
          s_b1 := Byte(pac[0]);
          s_b2 := Byte(pac[1]);
          s_b3 := Byte(pac[2]);
          s_b4 := Byte(pac[3]);
        end;
      end
      else
      begin
        raise Exception.Create('Error getting IP from HostName');
      end;
    end
    else
    begin
      raise Exception.Create('Error getting HostName');
    end;
  except
    FillChar(AInAddr, SizeOf(AInAddr), #0);
  end;
  WSACleanup;
end;
Zum besseren Verständnis hier noch der Header der Unit...
Delphi-Quellcode:
unit raw_ping;

interface
uses
  Windows, SysUtils, Classes;

type
  TSunB = packed record
    s_b1, s_b2, s_b3, s_b4: byte;
  end;

  TSunW = packed record
    s_w1, s_w2: word;
  end;

  PIPAddr = ^TIPAddr;
  TIPAddr = record
    case integer of
      0: (S_un_b: TSunB);
      1: (S_un_w: TSunW);
      2: (S_addr: longword);
  end;

 IPAddr = TIPAddr;

function IcmpCreateFile : THandle; stdcall; external 'icmp.dll';
function IcmpCloseHandle (icmpHandle : THandle) : boolean; stdcall; external 'icmp.dll'
function IcmpSendEcho (IcmpHandle : THandle; DestinationAddress : IPAddr;
           RequestData : Pointer; RequestSize : Smallint;
           RequestOptions : pointer;
           ReplyBuffer : Pointer;
           ReplySize : DWORD;
           Timeout : DWORD) : DWORD; stdcall; external 'icmp.dll';
  Mit Zitat antworten Zitat
BenTech

Registriert seit: 16. Jun 2003
Ort: Dortmund
60 Beiträge
 
Turbo Delphi für Win32
 
#5

Re: Kann das Speicherleck nicht finden...

  Alt 30. Dez 2005, 22:36
Habe das Problem aus lauter Verzweiflung jetzt folgendermaßen "gelöst"...

Delphi-Quellcode:
procedure TMyThreads.Execute;
begin
 Repeat
  if not paused then
  begin
   Online := Ping(InetAddress,TimeOut);
   Synchronize(UpdateMain);
  end;
  Sleep(300);
 Until Terminated;
end;
Ich verhindere, dass der Thread terminiert, indem ich eine Endlosschleife hineinpacke. Ausgeführt wird der Ping nur, wenn "paused" false ist. Nach der Schleife habe ich ein Sleep eingebaut, damit die CPU nicht unnötig belastet wird.

Jetzt tritt das Leck nichtmehr auf, da die Threads bestehen bleiben.

Falls jemand eine elegantere Lösung haben sollte, oder wenn jemand das Speicherleck doch noch finden sollte, wäre ich natürlich sehr dankbar

Ansonsten wünsche ich noch einen guten Rutsch ins neue Jahr
  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 06:42 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