AGB  ·  Datenschutz  ·  Impressum  







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

Initialisationsreinfolge

Ein Thema von himitsu · begonnen am 19. Mai 2006 · letzter Beitrag vom 2. Jul 2006
Antwort Antwort
Benutzerbild von himitsu
himitsu

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

Initialisationsreinfolge

  Alt 19. Mai 2006, 21:19
Moin,

hat zufällig noch wer 'ne Idee, wie man die Initialisationsreinfolge der im Projekt verwendeten Units auslesen kann?

In der PACKAGEINFO (Programmresource) stehen zwar alle Units drin (sogar mit Name), allerdings stimmt deren Reinfolge überhaupt nicht.

Es gibt dann zwar auch noch in den weiteren PackageInfos (im Programm) eine Liste, wo die Einsprungpunkte der Initialization- und Finalization-Abschitte, welche natürlich in der richtigen Reinfolge ist allerdings gibt es da (soweit ich das sehe) keine Möglichkeit die Namen der Units rauszufinden, oder zumindestens an welcher Stelle die aktuelle (da wo der TestCode drin ist) Unit sich versteckt.

Außerdem konnte ich auch noch nicht rausfinden, wie ich die Position dieser Tabelle in Erfahrung bringen kann (vom Programm aus - im Moment kann ich nur das Projekt compilieren, die Position auslesen und dann nochmals mit dem aktuellen Pointer compilieren ... siehe Anhang -.-'')




Ach ja, bevor hier sich jemand jetzt auf Biegen und Brechen verausgabt ...
eigentlich brauche ich die Lösung nicht wirklich, aber ich hab jetzt schon soviel Zeit darein gesteckt, daß mir 'ne Lösung schon gefallen würde

Mein Problem war, daß bei der Verwendung von ResourceString die verwendeten Strings am Anfang schon ausgelesen/aufgelistet/initialisiert werden und es somit schon vor der Ausführung der ersten Codezeile Speicher beim DelphiMM reserviert wurde.
Hab zumindestens das beoben, indem ich diese ResourceString's jetzt anders auslese und somit zusätzlich noch an die Unicodeversion dieser String rankomme ^^
Angehängte Dateien
Dateityp: exe project1_925.exe (373,5 KB, 16x aufgerufen)
Dateityp: zip project1_143.zip (1,8 KB, 10x aufgerufen)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: Initialisationsreinfolge

  Alt 23. Jun 2006, 14:31
na ja ... einen Versuch ist's wert ...
vielleicht findet sich ja noch wer an, der/die etwas weiß ... *push*
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#3

Re: Initialisationsreinfolge

  Alt 24. Jun 2006, 10:45
Ich, ich, meld

In Unit System.pas gibts eine Struktur PInitContext und eine lokale globale Variable InitContext: TInitContext.
In dieser Struktur gibts ein Member mit Namen InitCount und InitTable. InitCount enthält dabei die Anzahl der zu initialisierenden Units -> Addresse der Unit Sektion wo initialization und finalization steht. Jede Unit implementiert so eine Initialisierungs Sektion, egal ob der Programmierer sie im Source der Unit benutzt oder nicht.

Wir benötigen also den Zugriff auf die Variable InitContext, als erstes. Dazu einmalig irgend ein Program mit MAP Files kompilieren. Im MAP findet sich dann eine Sektion in der alle Variablen, egal ob globale verfügbar oder lokal geschützt, und deren Addressen. Du wählst nun eine globale Variable wie zb. AllocMemSize aus und berechnest zur Variablen InitContext den Addressoffset. Zur Laufzeit kannst du dann mit MyInitContext: PInitContext := PChar(@AllocMemSize) + Offset(InitContext - AllocMemSize) darauf zugreifen. Wir haben also die Speicheraddresse relativ zu einer globalen und fixen Addresse eine Variable ausgerechnet.

Nun können wir auf InitContext und deren Member zugreifen, im speziellen auf InitCount und InitTable. Über InitCount haben wir die Anzahl aller zu Initialisierenden Module, eg. Packages, und zu jedem dieser Packages/Module eine Tabelle mit den Adresszeigern auf die Units. DAS IST die exakte Reihenfolge wie auch die RTL alle Units initialisiert, also die reale Abhängigkeiten der Packages und Units.

Wir wandeln wir nun diese Zeiger in Namen der Packages und Units um ?

Die Packages sind sehr einfach: mit Module := FinHInstance(InitContext.InitTable[x]) erstmal das Modulhandle des Modules in dem sich die Units finden ermittelt. Dann mit GetModuleFileName(Module, ...) den Namen des Modules/Packages ermittelt.

Die Unitnamen sind da schon schwieriger. Eine Möglichkeit bietet die RTTI selber und mit Hilfe meiner EnumTypeInfo() Funktion (hier in der CodeLib) kann man alle RTTI zum ModuleHandle durch iterieren. Interessant sind dabei RTTIs wie Classen etc. pp. die nämlich selber intern den Unitnamen in denen sie implementiert wurden enthalten. Wir müssen nun nur noch die Zeiger die wir über die InitTable auf die Unit Initialization Addressen erhalten haben mit den Zeigern auf die RTTI dieser Units synchronisieren.
Eine andere Möglichkeit bieten die Packages und deren Resourcen selber. Ein Module enthält immer zwei Resourcen: PACKAGEINFO und DVCAL. PackageInfo enthält die Namen aller Units. Das dürfte die gleiche Reihenfolge sein wie ind der InitTable (aber nochmal testen).

Auf alle Fälle kommt man so an alle geladenen Module, alle Units ind den Modulen und alle deklarierten Datentypen der RTTI dynamisch zur Laufzeit des Programmes heran.

Gruß Hagen
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: Initialisationsreinfolge

  Alt 30. Jun 2006, 11:43
Den InitContext in der System.pas hatte ich ja schon gefunden, nur kommt man da ja leider nicht ran, jedenfalls nicht, wenn das Programm selber diesen finden soll.

Und was die PACKAGEINFO aus den Resourcen angeht ... leider stimmt da ja in keinster Weise die Reinfolge überein ... hab noch nichtmal ein Muster dort finden können, 's scheint wild durcheinander zugehen.

Siehe die EXE da oben.

Links ist ja die Initreinfolge aus'm InitContext, allerdings hatte ich mir die Position per Debuggen geholt, da ein entsprechender Pointer an InitExe/StartExe übergeben wird.
Also im Grunde war es auch der erstmal Kompilieren-Nachsehn-Anpassen-Weg ^^

Die passenden Unit-Namen (auf der linken Seite) hatte ich mir mal per "Hand rausgesucht und sie dort nur noch mal über'n Array mit angehängt, damit man den Unterschied zur rechten Seite sieht, wo die Namen der eingebundenen Units aus der PACKAGEINFO (Resourcen) aufgelistet sind.


Also wie gesagt, PACKAGEINFO bringt nichts und an den InitContext kommt bißher kein Code selbstständig ran
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#5

Re: Initialisationsreinfolge

  Alt 30. Jun 2006, 13:12
Zitat:
Also wie gesagt, PACKAGEINFO bringt nichts und an den InitContext kommt bißher kein Code selbstständig ran
Doch man kommt, das hatte ich aber oben schon beschrieben

Du kompilierst dein Modul mit .MAP Files. Suchst darin InitConntext und dessen Addresse und nimmst eine public globale Variable deiner Wahl aus Unit System.pas, deren Addresse und berechnet per Subtraktion einen Offset. Ausgehend von der Addresse der public Variablen + dem Offset berechnet aus dem Map File kannst du zur Laufzeit auf InitContext zugreifen. Das geht natürlich nur für eine jeweilige Delphi Version und ist wie immer bei solchen Sachen ein Hack/Trick. Aber was besseres kenne ich auch nicht.

Eines weis ich mit Gewissheit: mein Debugging Modul für mein modulares Frame Produkt benutzt diese Tricks und kann sehr wohl zur Laufzeit und dynamisch jeden Addressbereich zu einem Unitnamen auflösen. Dh. wir benötigen also die Namen der Units und die Addressbereiche die sie zur Laufzeit im Modul belegen. Und das ist ja was du suchst. Denn wenn man das hat weis man auch an Hand der Addressen der Init/Finit Prozeduren der Units deren Unitnamen, über InitContext die Reihenfolge in der Unit System.pas wie diese Init/Finit Prozeduren aufgerufen werden.

Gruß Hagen
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: Initialisationsreinfolge

  Alt 30. Jun 2006, 13:38
Zitat von negaH:
Das geht natürlich nur für eine jeweilige Delphi Version ...
Tja, und da liegt halt der Hund begraben ... daß sollte für ein OpenSourceProject sein und natürlich in den meisten Delphi-Versionen laufen
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#7

Re: Initialisationsreinfolge

  Alt 30. Jun 2006, 14:14
Leider fällt mir dann auch keine Lösung mehr ein, ausser man muß in jeder Unit Initialization eine externe Funktion aufrufen zum das zu protokollieren. (dürfte aber inakzeptabel sein nehme ich an)

Vielleicht ein Codekook/Trace in die Startup Funktion in Unit SysInit.pas, eventuell ?!
Die Einsprungandresse zum Startup Code können wir ja aus dem Modulheader auslesen.

Gruß Hagen
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

Re: Initialisationsreinfolge

  Alt 1. Jul 2006, 15:44
Zitat von negaH:
Vielleicht ein Codekook/Trace in die Startup Funktion in Unit SysInit.pas, eventuell ?!
Die Einsprungandresse zum Startup Code können wir ja aus dem Modulheader auslesen.
An etwas derartiges hatte ich zwar auch schon gedacht, allerdings taucht die entsprechende Adresse erst recht spät (fast am Ende) in der Initialisieungsprozedur auf und ich glaub kaum, daß irgendwer garantieren kann, daß sich an der Prozedur und damit am Offset (insprungadresse <> Pointer auf InitContext) nichts ändert -.-''

Leider ist es ja schade, daß es anscheinend keinen wirklich "guten" Weg gibt, denn dieses wäre auch 'ne gute Möglichkeit gewesen zu prüfen ob irgendwas im Programm eingebunden ist, ohne erst einen Querverweis daruf zu implementieren.
Also z.B. zu prüfen ob irgendein Modul und demnach auch die entsprechende Unit vorhanden ist.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#9

Re: Initialisationsreinfolge

  Alt 2. Jul 2006, 08:31
Ja ich weis Restriktionen haben die schlechte Angewohnheit das es einen Zeitpunkt geben kann wo sie hinderlich sind. Das betrifft eben im Besonderen auf Basisfunktionalitäten wie aus System.pas zu.

Gruß Hagen
  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 22:02 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