我在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
中的循环:这怎么可能?即如果它是一个僵局它不会停止,但永远挂起,对吧?
问题是:如何调试此问题?死锁是否可能导致此问题(即调试器刚停止)?
答案 0 :(得分:1)
尝试切换到CPU视图,然后使用F7进入有问题的TProc。有时这可以给你一个很好的暗示。
您还可以尝试在地图文件中查找“P”的地址。