![]() |
Alt -> Stacküberlauf
Hallo!
Ich habe einen wirklich merkwürdigen Fehler. Ich hab eine Komponente programmiert und wenn ich diese in ein Projekt mache und "Alt" drücke, dann gibt es einen Stack-Überlauf. Dabei muss meine Komponente nicht einmal den Fokus haben. Wenn man zum Beispiel gerade in einem Memo arbeitet und zufällig Alt drückt, stürzt das Programm ab. Um den Fehler zu suchen hab ich in allen von mir programmierten Methoden Haltepunkte gesetzt, allerdings wird beim Stacküberlauf keine von denen aufgerufen. Deshalb steh ich jetzt aufm Schlauch und weiß nicht wo ich suchen soll. Ich erwarte von euch keine Wunder, aber weiß jemand wo ich suchen könnte, hatte jemand schon ein ähnliches Problem oder habt ihr irgendwelche anderen Ideen??? Würde mich echt freuen :-D Grüße blablab |
AW: Alt -> Stacküberlauf
Irgendeine falsche Rekursion (Funktion ruft sich immer wieder selbst auf) in einem MainMenu-Eintrag drin, sobald der ausgewählt wird?
Stack Overflow passiert gewöhnlich meist dann, wenn sich eine Funktion immer wieder selbst aufruft. |
AW: Alt -> Stacküberlauf
Was zeigt denn der Stackcall an? Und welche Delphiversion hast du? Ich kann mich dunkel daran erinnern das dies ein Bug war/ist der sich glaub ich im Mainmenü verstekct hat.
|
AW: Alt -> Stacküberlauf
Ich benutze Delphi7. Ein MainMenu hab ich im Projekt nicht. Der Fehler tritt auch auf wenn ich ein leeres Projekt nur mit meiner Komponente habe.
Ich hab jetzt rausgefunden welche Methode sich immer wieder selbst aufruft:
Delphi-Quellcode:
Es wechselt immer wieder zwischen Zeile {x} und {y} hin und her bis zum Stacküberlauf.
procedure TWinControl.WMSysCommand(var Message: TWMSysCommand);
var Form: TCustomForm; function TraverseControls(Container: TWinControl): Boolean; var I: Integer; Control: TControl; begin Result := False; if Container.Showing then for I := 0 to Container.ControlCount - 1 do begin Control := Container.Controls[I]; if Control.Visible and Control.Enabled then begin if (csMenuEvents in Control.ControlStyle) and (Control.Perform(WM_SYSCOMMAND, TMessage(Message).WParam, TMessage(Message).LParam) <> 0) or (Control is TWinControl) and TraverseControls(TWinControl(Control)) then begin Result := True; Exit; end; end; end; end; begin with Message do begin if (CmdType and $FFF0 = SC_KEYMENU) and (Key <> VK_SPACE) and (Key <> Word('-')) and not IsIconic(FHandle) and (GetCapture = 0) and (Application.MainForm <> Self) then begin Form := GetParentForm(Self); {y} if (Form <> nil) and (Form.Perform(CM_APPSYSCOMMAND, 0, Longint(@Message)) <> 0) then Exit; end; { Broadcast WMSysCommand to all controls which have a csMenuEvents style. } {x} if (CmdType and $FFF0 = SC_KEYMENU) and TraverseControls(Self) then Exit; end; inherited; end; P.S. Stackcall??? :stupid: |
AW: Alt -> Stacküberlauf
Zitat:
Ein Stacküberlauf kommt, wenn der Speicher dafür ausgeht. Praktisch das OutOfMemory des Stacks. Der Stack wird z.B. durch lokale Variaben, Funktionsaufrufe (Rücksprungadresse) und Dergleichen gefüllt. also: - zuviele rekursive Funktionsaufrufe und/oder - zu viele/große lokale Variablen (welche im Stack liegen) |
AW: Alt -> Stacküberlauf
Er ruft sich hier immer wieder (indirekt) selbst auf, bei jedem aufruf speichert er sich ein paar lokale Variablen im Stack und irgendwann ist der Stack voll...
Delphi-Quellcode:
Es geht immer {1}...{8}{1}...{8}{1}...
procedure TWinControl.WMSysCommand(var Message: TWMSysCommand);
var Form: TCustomForm; function TraverseControls(Container: TWinControl): Boolean; var I: Integer; Control: TControl; begin {3} Result := False; if Container.Showing then for I := 0 to Container.ControlCount - 1 do begin Control := Container.Controls[I]; if Control.Visible and Control.Enabled then begin if (csMenuEvents in Control.ControlStyle) and {4} (Control.Perform(WM_SYSCOMMAND, TMessage(Message).WParam, TMessage(Message).LParam) <> 0) or (Control is TWinControl) and TraverseControls(TWinControl(Control)) then begin Result := True; Exit; end; end; end; end; begin with Message do begin {1}{5}if (CmdType and $FFF0 = SC_KEYMENU) and (Key <> VK_SPACE) and (Key <> Word('-')) and not IsIconic(FHandle) and (GetCapture = 0) and (Application.MainForm <> Self) then begin Form := GetParentForm(Self); if (Form <> nil) and {6} (Form.Perform(CM_APPSYSCOMMAND, 0, Longint(@Message)) <> 0) then Exit; end; { Broadcast WMSysCommand to all controls which have a csMenuEvents style. } {2} if (CmdType and $FFF0 = SC_KEYMENU) and TraverseControls(Self) then Exit; end; inherited; end; procedure TCustomForm.CMAppSysCommand(var Message: TMessage); type PWMSysCommand = ^TWMSysCommand; begin Message.Result := 0; if (csDesigning in ComponentState) or (FormStyle = fsMDIChild) or (Menu = nil) or Menu.AutoMerge then with PWMSysCommand(Message.lParam)^ do begin SendCancelMode(nil); {7} if SendAppMessage(CM_APPSYSCOMMAND, CmdType, Key) <> 0 then Message.Result := 1;; end; end; procedure TApplication.WndProc(var Message: TMessage); ... begin ... with Message do case Msg of ... CM_APPSYSCOMMAND: if MainForm <> nil then with MainForm do if (Handle <> 0) and IsWindowEnabled(Handle) and IsWindowVisible(Handle) then begin FocusMessages := False; SaveFocus := GetFocus; Windows.SetFocus(Handle); {8} Perform(WM_SYSCOMMAND, WParam, LParam); Windows.SetFocus(SaveFocus); FocusMessages := True; Result := 1; end; ... end; Jetzt muss ich nurnoch verstehen was er da macht und was ich falsch gemacht habe... |
AW: Alt -> Stacküberlauf
Wo kommt denn der Post plötzlich her :shock:
Du sendest WM_SYSCOMMAND und CM_APPSYSCOMMAND innerhalb der Funktion (WMSysCommand), welche diese Nachrichten auch verarbeitet ... endlosschleife Kennst du den PingPong-Witz? Scheibe links an die Klowand "Magst du Tennis, dann schau nach rechts" und rechts kommt "Magst du Tennis, dann schau nach links" dran. |
AW: Alt -> Stacküberlauf
Das ist ja nicht von mir, das ist ja der Delphi-Code...
Ich könnte versuchen [csMenuEvents] aus dem ControlStyle meiner Komponente herauszunehmen. In der Hilfe steht dazu "Das Steuerelement reagiert auf Befehle des Steuerungsmenüs." Was bedeutet das??? :stupid: |
AW: Alt -> Stacküberlauf
Ich hab jetzt [csMenuEvents] aus dem ControlStyle meiner Komponente herausgenommen. Dadurch gibts kein Stack-Überlauf mehr da Schritt {4} nicht mehr aufgerufen wird. Eigentlich änder ich ja nicht so gern einfach iwelche Eigenschaften ohne es wirklich zu verstehn was ich da mache. Aber dadurch geht der Fehler weg und anscheinend gehen keine Funktionen meiner Komponente verloren. Also was soll's :-D
Danke für eure Hilfe! |
AW: Alt -> Stacküberlauf
Zitat:
|
AW: Alt -> Stacküberlauf
Etwas spät aber:
Ich finde das sollte den Delphi-Programmieren zu denken geben, den immerhin tritt der Stacküberlauf ja nicht in meinem sondern in deren Code auf :-D |
AW: Alt -> Stacküberlauf
Das muß aber nicht bedeuten, daß der Ursache dafür nicht doch bei dir liegt.
Wenn ich den Busfahrer ablenke/erschlage, dann liegt der Fehler (Unfall) nicht beim Hersteller des Busses. |
AW: Alt -> Stacküberlauf
[OT]
Zitat:
|
AW: Alt -> Stacküberlauf
Aber nur, wenn der Hersteller dies nicht ausdrücklich in seinem AGBs ausschliesst.
|
AW: Alt -> Stacküberlauf
Ja gut, das stimmt schon. In irgendeiner Weise hab ich den Fehler natürlich selbst verursacht.
(Hätte ich meinen PC gar nicht erst angeschaltet, wäre es nicht zu dem Fehler gekommen :) ) Aber ich bin der Meinung, dass Delphi bei der falschen Verwendung mit einem Fehler reagieren sollte und nicht mit einem undurchsichtigen Stack-Überlauf. Das Beispiel sollte aber eher so lauten: Ich setze mich im Bus mit dem Kopf nach unten auf einen Sitz -> Bus kaputt. :-D |
AW: Alt -> Stacküberlauf
Zitat:
Denn dann wären 99,9% in Delphi nur noch Fehlererkennungscode und alle würden sich über die mindestens 200 MB einer leeren Anwendung aufregen :zwinker: |
AW: Alt -> Stacküberlauf
Wirklich? Seit ich Delphi programmiere war ich bis jetzt immer zufrieden mit der Fehlererkennung. Das ist der erste Fehler mit dem ich nicht zufrieden bin. Ich kann mir einfach nicht vorstellen dass es noch so viele derartige Fehler in Delphi gibt, falls es überhaupt noch welche gibt...
|
AW: Alt -> Stacküberlauf
Zitat:
|
AW: Alt -> Stacküberlauf
ohje. auf einen solchen Fehler zu stoßen find ich ja nicht so schlimm. Aber wenn du gleich auf mehrere stößt muss das ziemlich viel Arbeit und nervig sein...
|
AW: Alt -> Stacküberlauf
Vorallem in den Generics, den Record-Methoden und ähnlichen Dingen verstecken sich leider viele Compilerfehler, auf welche ich auch schon gestoßen bin. :(
Ich sagte ja nicht, daß nicht Vieles erkannt und auch benannt wird, aber "alles" geht einfach nicht und insgesamt ist wird halt dennoch nur ein winziger Teil erkannt/behandelt, auch wenn es im Vergleich zu einigen anderen Sprachen auch schon viel sein mag. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:55 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz