Delphi中生成表单/单元加载顺序列表的最佳方法是什么?

3

我遇到了一个问题,即每次启动时文件都会被删除,但我无法追踪到负责此问题的代码。最终,我将Vcl.Dialogs添加到所有单元中,并创建了一个初始化部分,其代码如下:

initialization
begin
  ShowMessage('Inside [Unit Name Here]');
end;

这真是件麻烦事。有没有一种简单的方法按照它们触发的顺序生成表单/单元列表?
更新:2019-08-01(有用的 MAP 链接)
以下是两个链接,可能有助于理解 DELPHI map 文件:
  1. http://docwiki.embarcadero.com/RADStudio/Rio/en/API_%28%2A.map%29

  2. Understanding Delphi MAP File


https://dev59.com/m67la4cB1Zd3GeqPWQzn#52103952 - Ken White
可能重复问题:https://dev59.com/wW855IYBdhLWcg3w6Y5q#4077426 - Remko
2个回答

8
你真的不需要费那么大劲去修改你的源代码单元。我认为你会发现使用下面的方法比通过某种方式生成一个单元列表,然后费力地查找要快得多。
如果你查看 System.Pas,你会发现一个类似于这样的 InitUnits 过程(来自 D7)。
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;
  [...]
  try
    while I < Count do
    begin
      P := Table^[I].Init;
      Inc(I);
      InitContext.InitCount := I;
      if Assigned(P) then
      begin
        TProc(P)();
      end;
    end;
  except
    FinalizeUnits;
    raise;
  end;
end;

这是引起每个单元初始化代码被调用的代码。它通过单元逐步执行并通过调用调用每个单元的初始化部分(如果有的话)。
  TProc(P)();

在循环之前检查Count的值;即使对于相对简单的项目,它的值可能高达几百。

在TProc(P)();行上设置断点,右键单击并将PassCount设置为Count值的一半。运行应用程序,当断点触发时,检查文件是否已被删除。

然后,您可以通过对Count的值进行二分搜索(如果文件仍然存在,则继续当前运行,或重置应用程序并将Pass Count减半)来确定确切地哪个单元会导致文件被删除。因为您可以使用二分搜索来完成这个过程,所以它将快速收敛到删除文件的单元。当断点触发时,您当然可以按下TProc(P)();上的F7键跟踪单元的初始化代码(如果已编译调试信息)。


调试入门,就像答案一样 ;) - whosrdaddy
1
你也可以在DeleteFile API处设置断点并观察调用堆栈(以解决“谁删除了我的文件”问题)? - Remko
@Remko:也许是这样,但这跟原帖所问的更远了。 - MartynA

7
您可以查看地图文件的segments部分。其中C=ICODE的条目是按执行顺序排列的具有初始化部分的单位。

在此处可以找到有关创建地图文件的信息:http://docwiki.embarcadero.com/RADStudio/Rio/en/API_%28%2A.map%29 - Michael Riley - AKA Gunny

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接