Указатель на экземпляр System.Monitor
каждого объекта сохраняется после всех полей данных. Если вы записываете слишком много данных в последнее поле объекта, может случиться так, что вы напишите поддельное значение по адресу монитора, что, скорее всего, приведет к падению, когда деструктор объекта попытается уничтожить поддельный монитор. Вы можете проверить, чтобы этот адрес был nil
в методе BeforeDestruction
ваших форм, для прямого порта Delphi 5 не должно быть назначено никаких мониторов. Что-то вроде
procedure TForm1.BeforeDestruction;
var
MonitorPtr: PPMonitor;
begin
MonitorPtr := PPMonitor(Integer(Self) + InstanceSize - hfFieldSize + hfMonitorOffset);
Assert(MonitorPtr^ = nil);
inherited;
end;
Если это проблема в вашем исходном коде, вы сможете обнаружить его в версии DLL вашей Delphi 5 с помощью диспетчера памяти FastMM4 со всеми активированными проверками. OTOH это также может быть вызвано увеличением размера символьных данных в сборках Unicode, и в этом случае они будут проявляться только в сборках DLL с использованием Delphi 2009 или 2010. По-прежнему будет хорошей идеей использовать последнюю версию FastMM4 со всеми проверками.
Edit:
Из вашей трассировки стека выглядит, что монитор действительно назначен. Чтобы выяснить, почему я бы использовал точку останова данных. Я не смог заставить их работать с Delphi 2009, но вы можете легко сделать это с WinDbg.
В обработчике OnCreate
вашей формы укажите следующее:
var
MonitorPtr: PPMonitor;
begin
MonitorPtr := PPMonitor(Integer(Self) + InstanceSize - hfFieldSize + hfMonitorOffset);
MessageDlg(Format('MonitorPtr: %p', [pointer(MonitorPtr)]), mtInformation,
[mbOK], 0);
DebugBreak;
// ...
Теперь загрузите WinDbg, откройте и запустите процесс, который вызывает вашу DLL. Когда форма будет создана, в окне сообщения будет показан адрес экземпляра монитора. Запишите адрес и нажмите ОК. Появится отладчик, и вы установите точку останова на доступ к записи для этого указателя, например:
ба w4 A32D00
заменив A32D00
на правильный адрес из окна сообщения. Продолжите выполнение, и отладчик должен достичь точки останова, когда монитор будет назначен. Используя различные представления отладчика (модули, потоки, стек), вы можете получить важную информацию о коде, который пишет по этому адресу.