For debugging our slow-starting Delphi XE3 application, we would like to log the initialization-phase of all used units in our system.
To complete this task, we need the Unit Name for each initialization call.
Analyzing the Data, when stepping through InitNames, we find the first Unit Name inside:
InitContext.InitTable^.TypeInfo.UnitNames
but we do not know how to fetch the appropriate Name from the Unit ID I before calling the Initialization procedure. Code Documentation says, TypeInfo.UnitNames contains the concatenated Unit Names of all Units.. But how do i travel between them? It is not an array nor a long string with seperators.
The code, where i would like to insert the log routine.
procedure InitUnits;
var
Count, I: Integer;
Table: PUnitEntryTable;
P: Pointer;
begin
if InitContext.InitTable = nil then
exit;
Count := InitContext.InitTable^.UnitCount;
I := 0;
Table := InitContext.InitTable^.UnitInfo;
{$IFDEF LINUX}
Inc(PByte(Table), InitContext.Module^.GOT);
{$ENDIF}
try
while I < Count do
begin
/////////////////////////////////////
MyLogCode( 'Unit: ' + Get UnitName here )
/////////////////////////////////////
P := Table^[I].Init;
Inc(I);
InitContext.InitCount := I;
if Assigned(P) and Assigned(Pointer(P^)) then
begin
{$IF defined(MSWINDOWS)}
TProc(P)();
{$ELSEIF (defined(POSIX) and defined(CPUX86))}
CallProc(P, InitContext.Module^.GOT);
{$ELSE}
TProc(P)();
{$ENDIF}
end;
end;
except
FinalizeUnits;
raise;
end;
end;
Recompiling the System.pas will be done via Arnaud Bouchez suggested solution.