delphi dll-finalization:如何调试

时间:2014-12-02 18:08:24

标签: delphi debugging dll dcom finalize

我在dll中遇到问题(包括COM对象):卸载dll时会执行一些终结部分,而有些部分则不会。

在调试器中我可以设法在System FinalizeUnits()中找到问题。此函数的伪代码 - 为方便起见:

procedure FinalizeUnits;
var
  Count: Integer;
  Table: PUnitEntryTable;
  P: Pointer;
begin
  if InitContext.InitTable = nil then
    exit;
  Count := InitContext.InitCount;
  Table := InitContext.InitTable^.UnitInfo;
  try
    while Count > 0 do
    begin
      Dec(Count);
      InitContext.InitCount := Count;
      P := Table^[Count].FInit;
      if Assigned(P) and Assigned(Pointer(P^)) then
      begin
        // ISSUE: when this is called for item x the debugging just stops
        // breakpoints in the except block or at the end of the function are not reached!
        TProc(P)(); 
      end;
    end;
  except
    FinalizeUnits;  { try to finalize the others }
    raise;
  end;
end;

有一个特定的终结呼叫导致问题:
InitContext.InitCount约为400,当执行项目x(例如363)时,调试器就会停止:它不会进入except块,也不会进入FinalizeUnits()函数的末尾(其中)我设置了断点) 顺便说一句:怎么可能?我认为在任何情况下都必须调用except块(或它之后的行)。

注释:

  • 当我手动避免此特殊调用时,所有其他函数都正常执行。
  • 当我走进有问题的TProc时,我最终进入TCriticalSection.Enter(然后Acquire - FSection.Enter - EnterCriticalSection - WSACleanup)< / LI>

WSACleanup调用的更多信息:我使用第三方库UniDAC打开与数据库的TCP / IP连接 - 我认为这个库在其中一个完成部分中调用WSACleanup(但我没有这个源代码)。 奇怪的是,当调试器位于WSACleanup行时:

function WSACleanup;        external     winsocket name 'WSACleanup';

我想要跳过它(即F8),调试器就停止了(好像应用程序已正常退出) - 但它应该继续FinalizeUnits中的循环:这怎么可能?即如果它是一个僵局它不会停止,但永远挂起,对吧?

问题是:如何调试此问题?死锁是否可能导致此问题(即调试器刚停止)?

1 个答案:

答案 0 :(得分:1)

尝试切换到CPU视图,然后使用F7进入有问题的TProc。有时这可以给你一个很好的暗示。

您还可以尝试在地图文件中查找“P”的地址。