![]() |
Stack überlauf
Ich habe einen Stack-Überlauf beim beenden der Anwendung.
Ich habe bei allen meinen WM_DESTROY Messagen Break Points gesetzt und nochmal genau geschaut ob hier durch ein erneutes Destroy in welcher Form auch immer WM_DESTROY abermals aufgerufen wird. Das ist nicht der Fall. Der Compiler geht ins CPU Fenster und das wars. (Bin kein ASM Freak so das ich daraus schlau werden könnte) Was muss ich beachten bzw. kann ich noch einstellen in den Debugger Option so das ich den Fehler lokalisieren kann. gruss |
AW: Stack überlauf
Na ja, in dem Fall ist der Aufruf-Stack (StackTrace) die erste Anlaufstelle, wo du reinschauen kannst/solltest.
Schön weit runter scrollen und mal nachsehn, was für Prozeduren vorher aufgerufen wurden. Der Stack muß nicht unbedingt durch zu viele Prozeduraufrufe überlaufen. Es kann auch durch zu viele und/oder zu große lokale Variablen passieren, welche ebenfalls da dauf landen. |
AW: Stack überlauf
Ach du meinst in dem Fenster Aufruf Stack?
wenn das so ist dann oops.. Ist wohl was spät heute. ;) EDIT: :00406544 MakeErrorMessage + $48 bleibt er stehn 1 zeile und die letzten zeilen :77010133 ntdll.KiUserExceptionDispatcher + 0xf :7705b63d ; ntdll.dll :7705b60f ; ntdll.dll :77010133 ntdll.KiUserExceptionDispatcher + 0xf :004066a9 @Halt0 + $85 :76ac336a kernel32.BaseThreadInitThunk + 0x12 :770392b2 ntdll.RtlInitializeExceptionChain + 0x63 :77039285 ntdll.RtlInitializeExceptionChain + 0x36 Werde ich auch nicht schlau draus. Zitat:
Das ist ein sehr seltsames verhalten.. Meine Vorgehensweise. Start 1 1.Starte Anwendung. 2. Starte mein Spectragram über Menü 3. Schließe das Spectragram über Menü 4. Starte es erneut auch über das Menü 5. Beende die Anwendung wenn beide Fenster offen sind. (X-Button) Keine Probleme. Start 2 1.Starte Anwendung. 2. Starte mein Spectragram über Menü 3. Beende die Anwendung wenn beide Fenster offen sind. (X-Button) Stack Überlauf. Start 3 1.Starte Anwendung. 2. Starte mein Spectragram über Menü 3. Beende die Anwendung wenn beide Fenster offen sind. (Über das Menü.. Beenden) Keine Probleme Kann es irgendwo nicht sein. gruss |
AW: Stack überlauf
Das sind schon die Namen der "letzten" aufgerufenen Prozeduren.
Scheint so, als wenn der in 'ner Exceptionbehandlung wieder 'ne Exception auslöst? :gruebel: Als Erstes erkennt man die "Schleife", wenn man 'ne Wiederholung sieht ... immer wieder eine/mehrere "gleiche" Aufrufe hintereinander. Das Hauptproblem ist, dass Delphi den Stacktrace nicht bis zum Ende Anfang auflistet, sondern nach einer gewissen Anzahl einfach stillschweigend aufhört. Ist auch OK, aber die "Trottel" hätten dann wenigstens einen "lade mehr" oder "lade alles"-Knopf einbauen sollen. :wall: Du kannst da nur versuchen "vorher" einzusteigen. z.B. in OnClose/OnCloseQuery/OnDestroy deiner Form einen Haltepunkt und dann versuchen mit F7/F8 weitergehen, bis du irgendwann in die Schleife rein kommst (in den ersten paar Durchläufen reicht der Stacktrace dann noch weit genug zurück. Oder du gehst in den aktuellen Stacktrace, suchst dir einen der Aufrufe aus und setzt da einen Haltepunkt drauf. (Doppelklick im Stacktrace und dann im Delphi- oder Assemblercode den Haltepunkt rein) Dann beenden (Strg+F2) und nochmal neu versuchen. Der Haltepunkt wird nun schon im ersten Durchlauf anhalten und der Stacktrace reicht dann hoffentlich auch weit genug zurück, damit man eine bessere/eigene Prozedur findet, die den Fehler eventuell ausgelöst hat. Problem ist dabei, dass der Haltepunkt auch schon während der Laufzeit anspringen könnte (falls die Procedur unglücklich öfters aufgerufen wird) * nochmal mit einem anderen Haltepunkt versuchen * oder den Haltepunkt "deaktivieren" (nicht löschen), das Programm starten lassen und dann kurz vorm Beenden ihn wieder aktivieren PS: Es gibt auch Haltepunktgruppen > man kann den Haltepunkt deaktivieren und gibt bei ihm eine Gruppe an (einfach einen Namen wählen), legt noch einen Haltepunkt z.B. ins OnClose und gibt beim ihm in den "weiteren" Haltepunkteigenschaften bei "Gruppe aktivieren" diese Gruppe an > kommst's Programm beim zweiten Haltepunkt vorbei, wird der erste Haltepunkt aktiviert und hält beim nächsten Mal an |
AW: Stack überlauf
Danke für die ausführlichen Infos.
Seltsam ist folgendes. Aus der Anwendung Vom Menü aus beendet..
Delphi-Quellcode:
Aus der DLL
IDM_Close:
DestroyWindow(MainHandle); Vom X Button beendet..
Delphi-Quellcode:
Beide Funktionen führen ein und die selben Funktionen aus.
case LoWord(wP) of
ID_CLOSE: begin // Anwendung beenden DestroyWindow(WinHandle); Result := True; Exit; end; Anwendung wird beendet
Delphi-Quellcode:
gut und die darauffolgenden Funktionen nach GetMessage.
WM_DESTROY:
begin if gnAudioChannel <> 0 then BassCloseChannel; if not INISave then SaveINI; PostQuitMessage(0); Result := 1; exit; end; Ich ändere nichts zwischen den einzelnen Start Ausführungen und trotzdem tritt so ein seltsames verhalten auf. Ich werde mal schauen ob ich mich da durchbeißen kann. gruss |
AW: Stack überlauf
Irgendwie bin ich jetzt echt .. sorry angepis..
Das Problem liegt an der Namensgebung und tritt nur bei einem Skin auf. Folder(Energy) nach Energys oder anderen beliebigen Namen umbenannt das Problem ist weg. Das kann es irgendwo nicht sein. So ein Problem mit Delphi hatte ich vorher noch nie. Wie kann das jetzt mit einem Stack Überlauf zusammen hängen. Habe alles gemacht Bilder ausgetauscht usw.. was halt so geht. Das umbenennen des Namen hat es dann gebracht aber warum ?? :wall: :kotz: Ich will den nicht verändern. EDIT: Ohne den Ordner umzubenennen bekomme ich das Problem nicht behoben. Keine Ahnung was das soll. Der Name des Ordners findet im Code selbst absolut keine Verwendung daher wundert es mich das es trotzdem Einfluss darauf hat. Ne, ne, ne. Da bekommt man die Krise. gruss |
AW: Stack überlauf
Mit den vorliegenden Informationen wird dir niemand sagen können woran das liegt.
Du benutzt doch dabei eine DLL, oder? Liegt die in der gleichen Projektgruppe und werden beide Projekte mit aktivierten Debuginformationen direkt in das Zielverzeichnis kopiert? Denn nur so bekommst du Projekt übergreifend ordentliche Stacktraces. MakeErrorMessage ist deine eigene Routine, oder? Dort kannst du ja einen Haltepunkt setzen. Hast du irgendwelche Exceptions unterdrückt, so dass Delphi dort beim Debuggen nicht anhält? |
AW: Stack überlauf
Zitat:
Zitat:
Zitat:
Zitat:
Die Meldung die ich jetzt bekomme ist diese (Aufruf-Stack Fenster) :002f1242 TInterfacedPersistent._Release + $12 :00409dd3 @IntfClear + $13 :004062e0 FinalizeUnits + $40 :004066a9 @Halt0 + $85 :7596336a kernel32.BaseThreadInitThunk + 0x12 :77d592b2 ntdll.RtlInitializeExceptionChain + 0x63 :77d59285 ntdll.RtlInitializeExceptionChain + 0x36 Das sind die einzigen. Diese kommen aber nicht wenn ich den Folder umbenenne wohlbemerk mit gleichen Code. Das kann es aber doch nicht sein. :wall: gruss |
AW: Stack überlauf
Hallo,
du arbeitest also mit Interfaces (?). eine der Interface-Variablen wurde bereits von Dir freigegeben, und jetzt versucht Delphi das auch noch mal. Das hatte ich letztens auch. Da half nur das explizite nil-Setzen. Das finnalize kannst du Debuggen, wenn du auf das end des Projektes einen Breakpoint setzt und dann F7 drückst. |
AW: Stack überlauf
Zitat:
Gruß K-H |
AW: Stack überlauf
Zitat:
Aber wie schon gesagt mein Problem kann\muss aber nichts mit meinem Code zu tun haben. Denn wenn ich den Folder umbenenne habe ich das Problem nicht. Und ich komme zum verrecken nicht darauf woran das liegt. Trotzdem Danke für deinen Ratschlag werde mich da mal drangeben. gruss |
AW: Stack überlauf
Zitat:
Wenn ich den Folder nach "Was denn nun" umbenenne oder einfach nur ein S anhänge "Energys" funktioniert alles und der Code läuft fehlerfrei durch. Ich habe versucht die Interface hart zu beenden (ohne Referenzzähler) bringt aber auch nichts.
Delphi-Quellcode:
PopupWindow := ISkinPopupWindow;
Beim beenden dann
Delphi-Quellcode:
(PopupWindow as ISkinPopupWindow).Free
PopupWindow := Nil; Aber das bringt alles nichts sobald ich den Namen verwende kracht es. Ist schwierig bei solchen Voraussetzungen. gruss |
AW: Stack überlauf
Zitat:
Aber ob mit oder ohne Referenzzählung, das kann nicht funktionieren. Sobald noch irgendwo ein Interface auf dieses schon freigegebene Objekt existiert, wird beim Finalisieren der Anwendung darin das _Release aufgerufen. Ist das Objekt schon freigegeben, passiert das auf diesem schon freigegebenen Objekt. Im günstigsten Fall knallt es direkt, z.B. wenn FastMM eingebunden ist, im ungünstigsten zerschießt du den Speicher und es knallt ganz woanders. Ein beliebtes Problem ist, dass ein Interface an eine DLL übergeben wird oder umgekehrt, aber beim Beenden nicht sauber wieder getrennt wird. Insbesondere kann ein Interface, das aus einer DLL kommt, in der Anwendung übrig bleiben, wenn die DLL entladen wird. Deshalb gibt es bei uns Shutdown-Prozeduren, in denen Listener usw. entfernt werden, so dass nach dem Entladen der DLLs keine Leichen übrig bleiben. Eine andere Möglichkeit wäre, dass du irgendwo ein Objekt als Objekt und Interface parallel nutzt. Solche Probleme kannst du mit FastMM aber oft schon direkt finden. |
AW: Stack überlauf
Zitat:
Habe es so eingetippt und nicht nachgedacht. Wie man am Bild sehen kann (ein langer Name für den Folder und kein Problem. ![]() Ich habe damit keinerlei Probleme. Das verstehe ich nicht. ![]() Und es kracht. gruss |
AW: Stack überlauf
Ich weiß nicht ob ich eine hilfe sein kann, weil ja schon alle die über die Interna Delphis bescheid wissen geantwortet haben.
Aber ich hatte auch mal ein Problem mit namen in Delphi und vielleicht nimmt der Stacküberlauf ja in einem ganz trivialen Problem den Anfang. Wegen der Message Queue soll man ja Formulare nicht mit Free zerstören sondern mit Release. Ich habe die Erfahrung gemacht dass man obwohl man ein Formular mit Release zerstört hat nicht sofort danach wieder ein Formular mit selben namen erzeugen kann. Es führt zu einer Exception. ...unique component name....bla Hab nen globalen ID counter an alle Formular-Namen anhängen müssen und ne eigene Methode für Namensvergleiche geschrieben um dem Herr zu werden. Kann es sein dass es irgendwo in deinem Projekt noch einen String "Energy" gibt der als Componentname Verwendung findet während des Abräumens der Anwendung? Vielleicht eine Liste von TCompoents oder so? |
AW: Stack überlauf
Hallo,
"Energy" darf der Ordner ja eh nicht heissen. Das Wort ist doch für uns Trekkies reserviert ;) |
AW: Stack überlauf
Engage...oder eben Energie.
![]() Ausser natürlich: ![]() Sherlock |
AW: Stack überlauf
Mal so ins Blaue
a) Vergrößere den Stack, dann gibt's keine Fehlermeldung mehr (nicht ernst gemeint) b) Verkleinere den Stack, dann knallt es früher, und vllt. an der richtigen Stelle. c) Was ist der Unterschied zwischen Energie/y und den anderen Skins abgesehen vom Namen? wird da etwas rekursiv aufgerufen? Und natürlich ganz banal, der Stack läuft über wenn man zuviel darauf schiebt. Ich weiß jetzt auch nicht mehr ob "Stack Frame" Dir beim Finden des Fehlers hilft. Irgendwann vor langer Zeit, war das auf jeden Fall empfehlenswert. Gruß K-H |
AW: Stack überlauf
Zitat:
Also wenn diese Soundmachine.exe heißt suche ich nach dem Konfigurationsfile Soundmachine.ske Wenn gefunden wird der Name des Folder als Skin identifiziert und damit zum Menu addiert. Daher verstehe ich den Bezug nicht warum nur wegen der Namensgebung ein Überlauf stattfindet. Zitat:
Klar kann ich einen anderen Namen verwenden nur das ist nicht der sinn der Sache. Zitat:
gruss |
AW: Stack überlauf
Kannst du mal ausprobieren, ob es an dem String Energy liegt, oder ob auch ein anderer Text mit gleicher Länge das Problem zeigt?
|
AW: Stack überlauf
Zitat:
Ok "123456" kracht "1234567" kracht nicht "12345" kracht nicht "Heilig" kracht. Es scheint ein Problem mit der String länge 6 vorzuliegen. Wie soll ich das beheben. :duck: gruss |
AW: Stack überlauf
Es ist vermutlich nicht der String selbst, sondern eine andere Variable, die je nach Stringlänge an anderer Position im Speicher liegt. Ab hier (eigentlich schon vorher) wird das jetzt aber reine Spekulation. Das Problem liegt offenbar ganz woanders und hat mit dem String Energy überhaupt nichts zu tun.
Es kann auch sein, daß der String (genauer die Stringlänge) irgendwie als etwas anderes interpretiert wird. Z.B. wenn vor dem String ein Array liegt und man dieses über seine Obergrenze hinaus liest. Zugegeben, sowas ist schwer zu finden. |
AW: Stack überlauf
Wie du schon sagst es liegt an der String länge. (Irrtum an den Strings im Speicher)
Zitat:
Frustrierend das ganze .. ;) Muss mir wohl mal das Spectragram vornehmen denn der Fehler tritt nur in Zusammenhang damit auf. gruss |
AW: Stack überlauf
Problem ist erledigt.
Habe in meinem Spectragram Window alle Controls deaktiviert und dann nach und nach wieder aufgesetzt. Dabei habe ich bemerkt das die Resourcen nicht zu meiner Virtuellen Liste addiert wurden. Zudem (einer meiner großen früheren Fehler) war die Variable zum übergeben der Strings in die Liste Global definiert. Das hatte zur folge das die Strings der (Handles, DC's, Pfade und die der Images) irgendwo ins Nirwana gelangt sind. Es wundert mich nur das es nicht schon früher gekracht hat. Danke für eure Hilfe. gruss |
AW: Stack überlauf
kleines Beispiel ... wird komplizierter, wenn der String noch irgendwo "verrechnet" wird (z.B. mit 'nem Pfad zusammengesetzt)
Delphi-Quellcode:
12 + (6+2)*2 = 28 // '123456'
type
// For System.pas internal use only. // Note, this type is duplicated in getmem.inc for diagnostic purposes. Keep in sync. PStrRec = ^StrRec; StrRec = packed record {$IF defined(CPU64BITS)} _Padding: Integer; // Make 16 byte align for payload.. {$ENDIF} codePage: Word; elemSize: Word; refCnt: Integer; length: Integer; end; Size := SizeOf(StrRec) + Length('123456' + #0#0) * SizeOf(Char) 12 + (5+2)*2 = 24 // '12345'
Delphi-Quellcode:
'1234567' liegt in SmallBlockTypes 32 und davor/dahinter sind 2 Byte Offset frei
type
SmallBlockTypes: array[0..NumSmallBlockTypes - 1] of TSmallBlockType =( {8/16 byte jumps} (BlockSize: 16{$ifdef UseCustomFixedSizeMoveRoutines}; UpsizeMoveProcedure: {$ifdef CPU386)}Move12{$else}Move8{$endif}{$endif}), (BlockSize: 24{$ifdef UseCustomFixedSizeMoveRoutines}; UpsizeMoveProcedure: Move20{$endif}), (BlockSize: 32{$ifdef UseCustomFixedSizeMoveRoutines}; ... '123456' liegt in SmallBlockTypes 32 und davor/dahinter sind 4 Byte Offset frei '12345' liegt in SmallBlockTypes 28 und davor/dahinter sind 0 Byte Offset frei Entweder wird mit diesem String irgendwas überschrieben (Overflow) oder irgendwas Anderes überschreibt da was und dein String landet nur zufällig in dem Block, wo das passiert. |
AW: Stack überlauf
Danke für die Infos..
Kann man sicher einmal gebrauchen ;) Wie gesagt bei mir war ein durcheinander bedingt dadurch das meine Variable global definiert war. Hat mich ja nur 2 Tage gekostet den Fehler zu finden :) gruss |
AW: Stack überlauf
Nachdem das Problem jetzt behoben ist habe ich mir einen neuen Skin gegönnt.
![]() Die Qualität der Bilder die man hier hochläd lassen echt zu wünschen übrig @Daniel sehr schlechte Qualität. Lohnt sich schon fast gar nicht mehr. Vergleich die einfach mal. Anhang gelöscht. gruss |
AW: Stack überlauf
Zitat:
Hochauflösende Fotos in Top-Qualität waren nie das Ziel. |
AW: Stack überlauf
Zitat:
Aber gut wie du willst ;) Nebenbei *.png ist alle mal kleiner sehe den sinn nicht ein Hochauflösendes Format zu komprimieren und dann ist es doch nicht kleiner. Es spart also keinen Platz auf deinen Server. na gut bei 100% Kompression schon. Ok werde dann in Zukunft nur noch verlinken. gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:56 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 by Thomas Breitkreuz