AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi TThread.Create erzeugt einen Stack Overflow?
Thema durchsuchen
Ansicht
Themen-Optionen

TThread.Create erzeugt einen Stack Overflow?

Ein Thema von glkgereon · begonnen am 2. Mär 2007 · letzter Beitrag vom 5. Mär 2007
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von glkgereon
glkgereon

Registriert seit: 16. Mär 2004
2.287 Beiträge
 
#1

TThread.Create erzeugt einen Stack Overflow?

  Alt 2. Mär 2007, 16:02
Hi,

Ich bastel mal wieder mit Threads rum.

folgender Code:
Delphi-Quellcode:
TConnectThread = class(TThread)
  private
    FTCP: TIdTCPClient;
    FHost: String;
    FPort: Integer;
    FConnected: Boolean;
  public
    procedure Execute; override;
    property TCP: TIdTCPClient read FTCP write FTCP;
    property Host: String read FHost write FHost;
    property Port: Integer read FPort write FPort;
    property Connected: Boolean read FConnected;
  end;

procedure TConnectThread.Execute;
begin
  Priority:=tpLower;
  FConnected:=False;
  FTCP.Connect(FHost,FPort);
  FConnected:=True;
end;
Delphi-Quellcode:
  try
    CT:=TConnectThread.Create(True); <--
    CT.FreeOnTerminate:=True;
    CT.TCP:=Fidtcp;
    CT.Host:=Host;
    CT.Port:=Port;
    T:=GetTickCount+5000;
    CT.Resume;
Wenn ich das ganze so aufrufe wird bei TConnectThread.Create eine Exception geworfen welche da lautet "Stack Overflow".
Das ganze kann man auch mit einem TThread machen, es passiert das selbe.

Das ganze wird in keiner Rekursion, ja noch nichtmal in einer Schleif aufgerufen, von daher verstehe ich absolut nicht was das soll

Hat da irgendwer eine idee?
»Unlösbare Probleme sind in der Regel schwierig...«
  Mit Zitat antworten Zitat
Benutzerbild von glkgereon
glkgereon

Registriert seit: 16. Mär 2004
2.287 Beiträge
 
#2

Re: TThread.Create erzeugt einen Stack Overflow?

  Alt 3. Mär 2007, 16:57
push
»Unlösbare Probleme sind in der Regel schwierig...«
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

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

Re: TThread.Create erzeugt einen Stack Overflow?

  Alt 3. Mär 2007, 17:39
Moin Gereon,

ich kann das Problem weder mit D7, noch mit D2006 nachvollziehen.
Wenn es wirklich am Konstruktor liegt, müsste das Problem allerdings auch bei jedem der TThread benutzt geschehen.

Übrigens gehört das Setzen von Eigenschaften nicht in Execute sondern in Create, und die das, private, Feld FConnected zu in Execute zu setzen ist völlig überflüssig, wenn Du FreeOnTerminate auf true setzt.
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
Benutzerbild von glkgereon
glkgereon

Registriert seit: 16. Mär 2004
2.287 Beiträge
 
#4

Re: TThread.Create erzeugt einen Stack Overflow?

  Alt 3. Mär 2007, 17:50
Mir ist schon klar dass es nicht an TThread liegt....ich benutze im selben Programm auch noch nen anderen Thread, und der funktioniert...


Ich stehe hier echt völlig vor einer Wand.
wie gesagt: es ist eigentlich nichts da was den Stack wirklich füllen könnte und trotzdem kommt ein Overflow...immer
»Unlösbare Probleme sind in der Regel schwierig...«
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#5

Re: TThread.Create erzeugt einen Stack Overflow?

  Alt 3. Mär 2007, 18:05
Hallo Gereon,

wenn CT eine Property mit einem Setter ist, könnte der Fehler dort zu suchen sein. Möglicherweise wird die Setter-Methode rekursiv aufgerufen.

Gruß Hawkeye
  Mit Zitat antworten Zitat
Benutzerbild von glkgereon
glkgereon

Registriert seit: 16. Mär 2004
2.287 Beiträge
 
#6

Re: TThread.Create erzeugt einen Stack Overflow?

  Alt 3. Mär 2007, 18:14
Zitat von Hawkeye219:
Hallo Gereon,

wenn CT eine Property mit einem Setter ist, könnte der Fehler dort zu suchen sein. Möglicherweise wird die Setter-Methode rekursiv aufgerufen.

Gruß Hawkeye
*nachguck*

nein, leider nicht. CT ist eine Lokale variable.

Aber jetzt kommt schon bei diesem Code eine AV:

Delphi-Quellcode:
  if FIdTCP.Connected then Exit;
  try
    Fidtcp.Connect(Host,Port);
Statt dem ganzen Thread gedöhns drumherum...
Aber erst beim Connect...Die Überprüfung auf Connected geht anstandslos.

Zitat:
In Projekt <abc> trat ein Problem mit folgender Meldung auf: 'access violation at 0x004061f0: write of address 0x00030060'. Prozess angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
Jetzt bin ich total verwirrt....
»Unlösbare Probleme sind in der Regel schwierig...«
  Mit Zitat antworten Zitat
Benutzerbild von DGL-luke
DGL-luke

Registriert seit: 1. Apr 2005
Ort: Bad Tölz
4.149 Beiträge
 
Delphi 2006 Professional
 
#7

Re: TThread.Create erzeugt einen Stack Overflow?

  Alt 3. Mär 2007, 18:54
Hat dein Thread keinen Konstruktor? bzw. wie sieht der aus?
Lukas Erlacher
Suche Grafiktablett. Spenden/Gebrauchtangebote willkommen.
Gotteskrieger gesucht!
For it is the chief characteristic of the religion of science that it works. - Isaac Asimov, Foundation I, Buch 1
  Mit Zitat antworten Zitat
Benutzerbild von glkgereon
glkgereon

Registriert seit: 16. Mär 2004
2.287 Beiträge
 
#8

Re: TThread.Create erzeugt einen Stack Overflow?

  Alt 3. Mär 2007, 19:33
Zitat von DGL-luke:
Hat dein Thread keinen Konstruktor? bzw. wie sieht der aus?
nein, ich habe den von TThread nicht überschrieben.
Brauchte ich in dem Fall nicht.
»Unlösbare Probleme sind in der Regel schwierig...«
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

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

Re: TThread.Create erzeugt einen Stack Overflow?

  Alt 3. Mär 2007, 20:16
Moin Gereon,

was passiert denn vor dieser Zeile:

CT:=TConnectThread.Create(True); <-- Ich vermute nämlich mal, dass die Ursache des Stack-Overflow an einer ganz anderen Stelle zu suchen ist, es dauert nur eine Weile, bis der Überlauf eintritt.
Auftreten kann der ja eigentlich nur durch ein nicht abbrechende Rekursion, ob die Rekursion nun absichtlich hervorgerufen wird, oder nicht.
Einer der "beliebtesten" Fehler in diesem Falle:
Innherhalb einer Getter-Methode einer Eigenschaft wird die Eigenschaft selber wieder gelesen.
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
Benutzerbild von glkgereon
glkgereon

Registriert seit: 16. Mär 2004
2.287 Beiträge
 
#10

Re: TThread.Create erzeugt einen Stack Overflow?

  Alt 3. Mär 2007, 20:32
Ok, also praktisch mal ein Backtrace was bis dahin passiert.
(Ich kann schonmal von vorneherein sagen: in meinem Code kommt weder eine Schleife noch eine absichtliche Rekursion vor... das mit den Gettern...nicht das es mir aufgefallen wäre)

Das ganze ist extrem gekürzt...
aber alles relevante sollte drin sein.

So, der ButtonClick
Delphi-Quellcode:
  TForm_Main = class(TForm)
  public
    I: TChatInterface;
    C: TChatClient;
  end;

procedure TForm_Main.FormCreate(Sender: TObject);
begin
  C.OnSleep:=Application.ProcessMessages;
end;

procedure TForm_Main.Btn_ConnectClick(Sender: TObject);
var ID: Integer;
    req: TChatDataPackage;
begin //Wir wollten unsern Client mit einem Server Verbinden
  if C.Connected then
  //Kommt nicht vor, wir sind noch nicht Connected...
  else
  begin
    ID:=I.ServerHistory.Add(Cmb_Hostname.Text); // Erstmal Servername speichern
    try
      C.Connect(I.ServerHistory[ID].Host,I.ServerHistory[ID].Port); //Verbinden
      req :=TChatDataPackage.Create('LOGIN',I.Profile.Nick,I.Profile.Passwd); //Login-Request Erstellen
      C.OnUserInput(req); //und absenden
      req.Free; //und wieder freigeben
    except
      on E: EConnectException do I.AddServer('Connection Failed'); //Wenns schiefgeht Fehlermeldung machen
    end;
  end;
  I.ServerHistory.Export2Strings(Cmb_HostName.Items); //Liste mit den Servern Updaten
end;
Aufgerufen wird zunächst C.Connected:
Delphi-Quellcode:
  TChatClient =class
    private
      Fidtcp: TIdTCPClient;
      FOnSleep: TOnSleep;
    public
      procedure Connect(Host: String; Port: Integer);
      function Connected: Boolean;
      property OnSleep: TOnSleep write FOnSleep;
  end;

procedure TChatClient.Connect(Host: String; Port: Integer);
var CT: TConnectThread;
    T: Cardinal;
    TT: TThread;
begin
  if FIdTCP.Connected then Exit;
  try
    CT:=TConnectThread.Create(True);
    CT.FreeOnTerminate:=True;
    CT.TCP:=Fidtcp;
    CT.Host:=Host;
    CT.Port:=Port;
    T:=GetTickCount+5000;
    CT.Resume;
    while (not CT.Terminated) do
    begin
      FOnSleep;
      if (T-GetTickCount<0) or (Fidtcp.Connected) then Break;
      Sleep(50);
    end;
    CT.Terminate;
    if not Fidtcp.Connected then raise EConnectException.Create('');
    FListeningThread.Resume;
  except
    raise EConnectException.Create('');
  end;
end;

function TChatClient.Connected: Boolean;
begin
  Result:=FIdTCP.Connected;
end;
Dann I.ServerHistory.Add
Delphi-Quellcode:
  TChatInterface = class (TObject)
  private
    FServerHistory: TServerHistory;
  public
    property ServerHistory: TServerHistory read FServerHistory;
  end;

type
  TServer = record
    Name: String;
    Host: String;
    Port: Integer;
  end;
  TServers = array of TServer;

  TServerHistory = class(TObject)
  private
    FItems: TServers;
    function Cmp(V1,V2: TServer): Integer;
  public
    function Add(S: String): Integer; overload;
    function Add(Name,Host: String; Port: Integer): Integer; overload;
    procedure Export2Strings(S: TStrings);
    property Items[ID: Integer]: TServer read GetItem; default;
  end;

function TServerHistory.Add(S: String): Integer;
var Name,Host: String;
begin //Ungeparsten Server in Liste schmeissen
  S:=Trim(S);
  if Pos('(',S)>0 then
  begin // "Name (Host:Port)"
    Name:=Copy(S,1,Pos(' (',S)-1);
    S:=Copy(S,Pos(' (',S)+2,Length(S)-Pos(' (',S));
  end;
  Host:=Copy(S,1,Pos(':',S)-1);
  Delete(S,1,Pos(':',S));
  Result:=Add(Name,Host,StrToInt(S));
end;

function TServerHistory.Add(Name, Host: String; Port: Integer): Integer;
var i, Akt, Hi, Lo: Integer;
    S: TServer;
begin //Server an sortierter Position einfügen
  S.Name:=Name;
  S.Host:=Host;
  S.Port:=Port;
  Hi:=High(FItems);
  Lo:=Low(FItems);
  if Hi<0 then Hi:=0;
  Akt:=Abs(Hi+Lo) div 2;
  while Hi-Lo<2 do
  begin //Richtige Stelle suchen
    i:=Cmp(FItems[Akt],S);
    case i of
      1: Hi:=Akt;
      0: Exit;
      -1: Lo:=Akt;
    end;
    Akt:=(Hi+Lo) div 2;
  end;
  SetLength(FItems,Length(FItems)+1);
  for i:=Akt to Length(FItems)-1 do
    FItems[i+1]:=FItems[i];
  FItems[Akt]:=S;
  Result:=Akt;
end;
Dann kommt C.Connect(I.ServerHistory[ID].Host,I.ServerHistory[ID].Port)
der Zugriff auf I.ServerHistory und C.Connect steht ja oben schon
»Unlösbare Probleme sind in der Regel schwierig...«
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 21:38 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