这个问题可能会或可能不会解决我的问题 - 但我希望了解Delphi / Windows如何以可能导致此问题的方式运作。
我有一个使用第三方组件加载Outlook .msg文件的应用程序。
在某些情况下(特定邮件),应用程序在调用SetLength时会冻结(在组件内部,我有源代码)。 有时在从文件(流)加载属性的过程内调用setLength时会发生这种情况。它发生在同一邮件上完全相同的地方 - 并且每次都可以复制。
显然,该组件会做很多事情,这可能是其中一些副作用。但是,邮件包含我无法发送给第三方组件开发人员的机密数据,因此我无法将其发送给他进行调试。
该程序在域上的Windows XP下运行。 奇怪的是,它只发生在运行程序的用户未设置为本地计算机的管理员时。
ms := TMemoryStream.Create;
try
WriteStorageToStream(SubStorage, ms);
ApplyValue(ms, ms.Size)
finally
ms.Free;
end;
procedure ApplyValue(Stream: TStream; brLen: Integer);
var
s: AnsiString;
begin
SetLength(s, brLen); // this freezes it all. brLen=3512
FillChar(s[1], brLen, #0);
Stream.Read(s[1], brLen);
Value := s;
end;
我不知道WriteStorageToStream究竟做了什么,但由于我们没有操纵流并且brLen有一个整数值,我认为它是无关紧要的。
答案 0 :(得分:1)
SetLength绝对没有理由冻结只有3512个字符长的AnsiString。你怎么确定它在那里冻结而不是早些时候(比如在WriteStorageToSteam中)?大概是你在调试器中踩过这个。当它被冻结时,CPU是否在该进程线程上达到100%?它只在某些电子邮件上冻结的事实告诉我,这些电子邮件内容中的某些内容导致冻结。对SetLength的调用与内容无关;它只关心长度。
答案 1 :(得分:1)
我会说这是简单的内存覆盖,当调用SetLength然后尝试使用内存管理结构时,导致内存管理器失败。问题出在WriteStorageToStream(SubStorage,ms);
要找到它,请使用FastMM调试版本,并打开内存覆盖检测选项。