繁体   English   中英

delphi dll最终化:如何调试

[英]delphi dll-finalization: how to debug

我在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

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

function WSACleanup;        external     winsocket name 'WSACleanup';

并且我想跨过它(即F8),调试器就停止了(就像应用程序正常退出一样)-但是它应该在FinalizeUnits继续循环:这怎么可能? 即,如果这是一个僵局,它不会停止,而是永远挂下来,对吗?

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

在使用F7进入有问题的TProc之前,请尝试切换到CPU视图。 有时这可以给您一个很好的提示。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM