AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

FastMM4 und Delphi 7

Ein Thema von Bernd1982 · begonnen am 1. Jan 2018 · letzter Beitrag vom 2. Jan 2018
Antwort Antwort
Bernd1982

Registriert seit: 22. Dez 2009
11 Beiträge
 
#1

AW: FastMM4 und Delphi 7

  Alt 2. Jan 2018, 00:25
Genau so sollte es sein. Isses aber leider nicht FastMM4 kommt trotzdem später...

Kannst Du mir bitte nochmal einen Hinweis zu dem UseOutputDebugString geben? Wie aktiviere ich das? Wo und wie kann ich das Log lesen?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: FastMM4 und Delphi 7

  Alt 2. Jan 2018, 00:32
Aktivieren: in der Options-INC des FastMM

OutputDebugString wird an den Debugger geschickt, wenn Einer verbunden ist. (Programm im Debugger gestartet)
Und Delphi schreibt das dann ins Ereignisprotokoll, welches in der Debug-Ansicht standardmäßig angezeigt wird. (Ansicht > Debugfenster > Ereignisprotokoll)
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Bernd1982

Registriert seit: 22. Dez 2009
11 Beiträge
 
#3

AW: FastMM4 und Delphi 7

  Alt 2. Jan 2018, 00:49
Danke. Hab' das {$define UseOutputDebugString} aktiviert. Hilft aber auch nix, der FastMM4 wird ja gar nicht erst lebendig

Mir gehen die Ideen aus, wie ich die Reihenfolge der Units beeinflussen könnte. Einen Virus habe ich wahrscheinlich nicht. Mein Avira würde den wahrscheinlich entdecken und als Admin habe ich das Delphi nur einmal gestartet nach der Installation.

Jetzt gehe ich erst mal ratlos zu Bett... Danke Dir für Deine Unterstützung!
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#4

AW: FastMM4 und Delphi 7

  Alt 2. Jan 2018, 05:26
Warum da noch selbst mit den Directiven rumspielen verwende doch einfach FastMM4Options
http://jedqc.blogspot.de/2007/07/new...interface.html

gruss
  Mit Zitat antworten Zitat
Bernd1982

Registriert seit: 22. Dez 2009
11 Beiträge
 
#5

AW: FastMM4 und Delphi 7

  Alt 2. Jan 2018, 16:26
Ich habe das Problem auf eine sehr spezielle Art gelöst. Es bleibt dabei, bei meinen über hundert Units wird FastMM vom Compiler nicht an der frühen Stelle initialisiert, sondern erst nachdem andere Units schon Speicher vom alten MemoryManager angefordert haben. FastMM4 tritt daher so seinen Dienst nicht an. Die Reihenfolge wird vom Compiler festgelegt, so dass man zunächst keine Möglichkeit hat einzugreifen. Aber es geht doch

Ich habe nämlich 2 Änderungen gemacht:
  1. Ich habe die INITILAIZATION in FastMM4.pas mit ASM NOP NOP NOP NOP END; als Kennung anfangen lassen.
  2. Ich habe die system.pas geändert und neu kompiliert. Bei InitUnits wird jetzt zuerst die FastMM4 gesucht und früher initialisiert als vom Compiler vorgegeben.

Zu 1.: Die FastMM4.pas sieht am Ende jetzt also so aus:
Delphi-Quellcode:
initialization
  asm
  NOP
  NOP
  NOP
  NOP
  end;
  RunInitializationCode;
finalization
{$ifndef PatchBCBTerminate}
  FinalizeMemoryManager;
{$endif}
end.
Die 4 NOPs ergeben 4 x $90 also ein DWORD $90909090 im Code. Daran kann man diese Unit in der Liste erkennen.

Zu 2.: Der Compiler legt im Quellcode eine Liste an, die aus je 2 Pointern auf Prozeduren für jede Unit besteht: Init für die Initialisierung und FInit für die Finalisierung. Bevor beim Programmstart nun alle Units nacheinander in InitUnits in system.pas initialisiert werden, suche ich zuerst nach meinem Eintrag mit $90909090. Die Nummer in der Liste merke ich mir dann in der Variablen iFastMM4. Beim Initialisieren wird die Liste vorwärts abgearbeitet, beim Finalisieren rückwärts. Wenn die 5. Unit dran wäre, initialisiere ich dann immer erst die FastMM4. Wenn die FastMM4 regulär dran wäre ignoriere ich sie. Beim Finalisieren, wie gesagt, genau anders herum:
Delphi-Quellcode:
VAR iFastMM4:LongInt=-1; {Falls die Unit FastMM4 früher behandelt werden muss}

procedure FinalizeUnits;
var
  i,Count: Integer;
  Table: PUnitEntryTable;
  P: Pointer;
begin
  if InitContext.InitTable = nil then
    exit;
  Count := InitContext.InitCount;
  Table := InitContext.InitTable^.UnitInfo;
  try
    FOR i:=Count-1 DOWNTO 0 DO BEGIN
      InitContext.InitCount:=i;
      IF i=iFastMM4 THEN Continue;
      P:=Table^[i].FInit;
      IF Assigned(P) THEN TProc(P)();
      IF (i=5) AND (iFastMM4>-1) THEN BEGIN
        InitContext.InitCount:=iFastMM4+1;
        TProc(Table^[iFastMM4].FInit)() {erst die 5, dann FastMM4}
      END;
    END;
  except
    FinalizeUnits; { try to finalize the others }
    raise;
  end;
end;

const
  errCaption: array[0..5] of Char = 'Error'#0;

{***********************************************************}

procedure InitUnits;
var
  Count,i: Integer;
  Table: PUnitEntryTable;
  P,P1: Pointer;
begin
  if InitContext.InitTable = nil then
    exit;
  Count := InitContext.InitTable^.UnitCount;
  Table := InitContext.InitTable^.UnitInfo;
{$IFDEF LINUX}
  Inc(Cardinal(Table), InitContext.Module^.GOT);
{$ENDIF}
  try
    FOR i:=0 TO Count-1 DO BEGIN {Unit FastMM4 suchen}
      P:=Table^[i].Init;
      IF Assigned(P) THEN BEGIN
        P1:=P;
        Inc(DWord(P1),9);
        IF DWord(P1^)=DWord($90909090) THEN BEGIN {Initialisierung der Unit FastMM4 gefunden! (muss dort mit ASM NOP NOP NOP NOP END anfangen! NOP=$90)}
          IF I<=7 THEN Break;
          iFastMM4:=I;
          Break;
        END;
      END;
    END;

    FOR i:=0 TO Count-1 DO BEGIN
      InitContext.InitCount:=i+1;
      IF i=iFastMM4 THEN Continue;
      IF (i=5) AND (iFastMM4>-1) THEN BEGIN
        InitContext.InitCount:=iFastMM4+1;
        TProc(Table^[iFastMM4].Init)() {erst FastMM4, dann die 5}
      END;
      P:=Table^[i].Init;
      IF Assigned(P) THEN TProc(P)();
    END;
  except
    FinalizeUnits;
    raise;
  end;
end;
Die system.pas muss man manuell im CMD-Fenster mit dem Kommandozeilencompiler DCC32 kompilieren:

"C:\Program Files (X86)\Borland\Delphi7\Bin\DCC32.EXE" -$D+ -Y SYSTEM

und ohne Debug-Info:

"C:\Program Files (X86)\Borland\Delphi7\Bin\DCC32.EXE" -$D- -Y SYSTEM

Die geänderte system.pas kommt zurück nach "C:\Program Files (x86)\Borland\Delphi7\Source\Rtl\Sys", die entstandene system.dcu mit Debug-Info nach "C:\Program Files (x86)\Borland\Delphi7\Lib\Debug" und die ohne nach "C:\Program Files (x86)\Borland\Delphi7\Lib". Ggf. muss man zum Kopieren Admin-Rechte haben. Es ist nicht verkehrt, vorher alles zu sichern!

Wenn man in system.pas debuggen will, muss man in den Projekt-Optionen bei Compiler die Option [ ] mit Debug-DCUs aktivieren.

Das ist wirklich eine harte Nuss gewesen! Bestimmt hätte es auch eine einfachere Lösung gegeben, habe ich aber nicht gefunden. Es ist mir unbegreiflich, warum die FastMM.pas so spät initialisiert wird, obwohl sie oben im *.dpr als erstes stand. Egal - danke für Eure Hilfe.
  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 03:19 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