AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Program crasht beim Schließen, aber...
Thema durchsuchen
Ansicht
Themen-Optionen

Program crasht beim Schließen, aber...

Ein Thema von freejay · begonnen am 24. Feb 2020 · letzter Beitrag vom 27. Feb 2020
Antwort Antwort
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.326 Beiträge
 
Delphi 12 Athens
 
#1

AW: Program crasht beim Schließen, aber...

  Alt 25. Feb 2020, 01:52
Sowas kann man per se sich auch selbst schnell bauen.
Eigentlich würde es reichen, wenn man das FreeMemory überschreibt und dort den Inhalt "zerstört", dann werden Zugriffe nach dem Free fehlschlagen.

Der wichtige Teil ist natürlich das FillMemory/FillChar.
Delphi-Quellcode:
function MyFreeMem(P: Pointer): Integer;
begin
  FillMemory(P, UnknownSize, $A5); // 1010 0101 = HighBit + Odd
  Result := SysFreeMem(P);
end;

var
  MemMgr: TMemoryManagerEx;

initialization
  GetMemoryManager(MemMgr);
  MemMgr.FreeMem := MyFreeMem;
  SetMemoryManager(MemMgr);

finalization
  GetMemoryManager(MemMgr);
  MemMgr.FreeMem := SysFreeMem; // oder MemMgr.FreeMem im Init speichern
  SetMemoryManager(MemMgr);

end.
Aber leider ist es nicht so einfach im FreeMem die Größe rauszubekommen.
(wäre auch zu einfach gewesen, wenn diese MemoryAPI uns den Wert direkt als Parameter geben würde )

Im Windows (wenn FastMM verwendet) könnte erstmal rausfinden in was für einem Block (SmallXXX, Medium oder Large) der Speicher liegt
und dementsprechend dann auslesen wie groß der Speicher ist (inkl. dem zusätzlichen Speicher dahinter).
Bei den Small ist die Größe bekannt und bei den Anderen steht sie (ähnlich wie hier) vor den Daten gespeichert.

In Liunx/MacOS/iOS/Android kann es nochmal anders aussehn.

Nja, also der umständlicheren Einfachheit halber einfach die Größe noch mit einfügen, um schnell und sicher den Wert vom GetMem zu bekommen.
Delphi-Quellcode:
function MyGetMem(Size: NativeInt): Pointer;
begin
  Inc(Size, SizeOf(Integer));
  Result := SysGetMem(Size);
  PInteger(Result)^ := Size;
  Inc(NativeInt(Result), SizeOf(Integer));
end;

function MyFreeMem(P: Pointer): Integer;
begin
  Dec(NativeInt(P), SizeOf(Integer));
  FillMemory(P, PInteger(P)^, $A5); // 1010 0101 = HighBit + Odd
  Result := SysFreeMem(P);
end;

function MyReallocMem(P: Pointer; Size: NativeInt): Pointer;
begin
  Dec(NativeInt(P), SizeOf(Integer));
  Inc(Size, SizeOf(Integer));
  Result := SysReallocMem(P, Size);
  PInteger(Result)^ := Size;
  Inc(NativeInt(Result), SizeOf(Integer));
end;

function MyAllocMem(Size: NativeInt): Pointer;
begin
  Inc(Size, SizeOf(Integer));
  Result := SysAllocMem(Size);
  PInteger(Result)^ := Size;
  Inc(NativeInt(Result), SizeOf(Integer));
end;

var
  MemMgr: TMemoryManagerEx;

initialization
  GetMemoryManager(MemMgr);
  MemMgr.GetMem := MyGetMem;
  MemMgr.FreeMem := MyFreeMem;
  MemMgr.ReallocMem := MyReallocMem;
  MemMgr.AllocMem := MyAllocMem;
  SetMemoryManager(MemMgr);

finalization
  GetMemoryManager(MemMgr);
  MemMgr.GetMem := SysGetMem;
  MemMgr.FreeMem := SysFreeMem;
  MemMgr.ReallocMem := SysReallocMem;
  MemMgr.AllocMem := SysAllocMem;
  SetMemoryManager(MemMgr);

end.
und nicht vergessen, dass dieses in der DPR als erste Unit im Uses sein muß
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (25. Feb 2020 um 11:00 Uhr) Grund: das komische "Allert" entfernt
  Mit Zitat antworten Zitat
Incocnito

Registriert seit: 28. Nov 2016
229 Beiträge
 
#2

AW: Program crasht beim Schließen, aber...

  Alt 25. Feb 2020, 08:03
Leider etwas ab vom Thema, aber mit dem Memory-Manager habe ich 0 Erfahrung, daher interessiert mich das gerade ...
1) Du mischt in deinem Beispielcode Integer und NativeInt (zumindest für mich augenscheinlich), ist das ein "Fehler"
der nicht so schlimm ist, da die meisten 32-Bit-Anwendungen schreiben, oder muss das tatsächlich so aus einem
bestimmten Grund, oder ist das Beispiel unvollständig (sieht vollständig aus) und läuft so eh nicht, oder ...?
2) Was ist "Alert" im initialization-Block? Ohne Semikolon? In der Delphi-Hilfe habe ich (so auf die Schnelle)
nichts finden können.

Sorry, dass ich hier Off-Topic schreibe, aber ich verweise nun ja auf einen Post, daher denke ich ist das hier
sinnvoller als einen eigenen Thread auf zu machen.

LG
Incocnito
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.326 Beiträge
 
Delphi 12 Athens
 
#3

AW: Program crasht beim Schließen, aber...

  Alt 25. Feb 2020, 10:59
Ja, das Mischen war Absicht, um besser erkennen zu können was wo damit gekeint ist.
NativeInt für den Pointer-Cast und Integer für die Size.

Nochmal überlegt wäre in Bezug auf 64 Bit IntPtr für Pointer-Cast und NativaInt für die Size wohl besser, falls doch jemand einen Speicherblock größer als 2 bzw. 4 GB reservieren will.


Allert?
Upsss, keine Ahnung ... da hab ich wohl geschlafen, beim Copy&Paste.


Wie gesagt, der "eigentliche" Code besteht hier nur aus dem FillMemory bzw. FillChar, womit der Speicher zerstört und mit Bytes gefüllt wird, die einen Fehler provizieren sollen, sobald jemand darauf zugreift.



Es trifft natürlich nicht alle Fälle, denn wenn etwas Anderes diesen Speicher inzwischen wiederverwendet ... wenn das ein Objekt ist, dann wird Free natürlich weiterhin falsch ausgerührt.
Hier könnte man die eigentliche Freigabe im MM noch verzögern (für kleinere Speicherblöge, da Objekte ja selten groß sind)
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
freejay

Registriert seit: 26. Mai 2004
Ort: Nürnberg
273 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Program crasht beim Schließen, aber...

  Alt 25. Feb 2020, 13:04
Danke schon mal für die Tipps.

Wie ich jetzt FastMM ausprobieren wollte, ist das nächste komische Problem aufgetaucht (ist nicht durch FastMM verursacht):

Im Moment kann ich das Projekt IM DEBUG MODUS nicht mal starten. Da kommt ein Fehler in der Funktion GetDynaMethod in Unit System in der markierten Zeile:

Delphi-Quellcode:
function GetDynaMethod(vmt: TClass; selector: SmallInt): Pointer;
{$IFDEF PUREPASCAL}
type
  TDynaMethodTable = record
    Count: Word;
    Selectors: array[0..9999999] of SmallInt;
    {Addrs: array[0..0] of Pointer;}
  end;
  PDynaMethodTable = ^TDynaMethodTable;
var
  dynaTab: PDynaMethodTable;
  Parent: Pointer;
  Addrs: PPointer;
  I: Cardinal;
begin
  while True do
  begin
    dynaTab := PPointer(PByte(vmt) + vmtDynamicTable)^; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<
    if dynaTab <> nil then
    begin
      for I := 0 to dynaTab.Count - 1 do
        if dynaTab.Selectors[I] = selector then
        begin
          Addrs := PPointer(PByte(@dynaTab.Selectors) + dynaTab.Count * SizeOf(dynaTab.Selectors[0]));
          Result := PPointer(PByte(Addrs) + I * SizeOf(Pointer))^;
          Exit;
        end;
    end;
    Parent := PPointer(PByte(vmt) + vmtParent)^;
    if Parent = nil then Break;
    vmt := PPointer(Parent)^;
  end;
  Result := nil;
end;
{$ELSE !PUREPASCAL}
...
Eigentlich wird im normalen Quelltext nur eine Action auf enabled bzw. disabled gesetzt (nicht erschrecken: uralter Quelltext mit deutschen Bezeichnungen... ):

  Form1.acDateiSpeichern.Enabled := Form1.bVeraendert; Ich bekomme keinen Fehler, wenn ich die RELEASE VERSION starte...

Irgendwelche Ideen dazu???
[Delphi 11.3.1 Enterprise; Win10/11; MySQL; VCL]
  Mit Zitat antworten Zitat
freejay

Registriert seit: 26. Mai 2004
Ort: Nürnberg
273 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Program crasht beim Schließen, aber...

  Alt 25. Feb 2020, 13:11
PS: Ich verwende keine Pointer und auch praktisch keine Variablen, die auf Objekte zeigen...
[Delphi 11.3.1 Enterprise; Win10/11; MySQL; VCL]
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.326 Beiträge
 
Delphi 12 Athens
 
#6

AW: Program crasht beim Schließen, aber...

  Alt 25. Feb 2020, 15:19
Form1 oder acDateiSpeichern ist dann wohl nil/ungültig.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
freejay

Registriert seit: 26. Mai 2004
Ort: Nürnberg
273 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Program crasht beim Schließen, aber...

  Alt 25. Feb 2020, 15:53
Form1 oder acDateiSpeichern ist dann wohl nil/ungültig.
Die Zuweisung an die Action acDateiSpeichern löst eine Übertragung des Enabled-Status auf Controls, die diese Action als Action eingebunden haben aus. Und da geht's schief (Unit System.Action):


Delphi-Quellcode:
procedure TContainedAction.SetEnabled(Value: Boolean);
var
  I: Integer;
begin
  if Value <> FEnabled then
  begin
    if Assigned(ActionList) then
    begin
      if ActionList.State = asSuspended then
      begin
        FEnabled := Value;
        Exit;
      end
      else if (ActionList.State = asSuspendedEnabled) then
        Value := True;
    end;
    for I := 0 to ClientCount - 1 do
      if Clients[I] is TContainedActionLink then
        TContainedActionLink(Clients[I]).SetEnabled(Value); // <<<<<<<<<<<<<<<<<<<<<<<<<<<
    FEnabled := Value;
    Change;
  end;
end;
Wenn mir jetzt jemand verraten könnte, wie ich an den Namen des Controls, das mittels Client[i] mit der Action verbunden ist, rankomme...
[Delphi 11.3.1 Enterprise; Win10/11; MySQL; VCL]
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.326 Beiträge
 
Delphi 12 Athens
 
#8

AW: Program crasht beim Schließen, aber...

  Alt 25. Feb 2020, 18:56
ActionLink.Action.ActionComponent ?

Wenn das nicht hilft, dann könnte man sich noch aus ActionLink.OnChange das Objekt des Methoden-Zeigers extrahieren.
Ein Therapeut entspricht 1024 Gigapeut.
  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:15 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