Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2003.10.13;
Скачать: [xml.tar.bz2];

Вниз

Любопытная (и неприятная) проблема с DLL и run-time packages   Найти похожие ветки 

 
Digitman   (2003-09-23 16:15) [0]

Среда - W2kPro(eng) + SP3, D5 (Update 1 , build 6.18)

Исходные данные :
1. Текст DLL-проекта

library MyDll;
uses Windows, Messages, SysUtils;
begin
ExitCode := 1;
end;

сборка с RTP (задействован только VCL50.BPL)

2. Фрагмент текста хост-приложения

procedure TMyForm.Button1Click(...);
var
hModule : THandle;
begin
hModule := LoadLibrary("MyDll.dll"); // [1]
end;

Проблема :
При выполнении строчки [1] (осн.код.поток хост-процесса) происходит неперехватываемое AV-исключение, чего здесь быть не должно ни коим образом.

В то же время, если сборку DLL выполнить без RTP, то все работает как положено, ожидаемым образом : система по LoadLibrary() возвращает 0 с кодом ошибки, фиксирующим отказ при инициализации DLL (эмулируемый нами таким вот простейшим образом)

Вопрос :

Кто-либо в какой-либо среде наблюдает ли сходное явление ? Прошу поделиться соображениями по сему поводу.


 
Ketmar   (2003-09-23 16:45) [1]

ShareMem вставить не помогло?


 
Владислав   (2003-09-23 16:47) [2]

> Digitman © (23.09.03 16:15)

Бред какой то... Казалось бы, нет для этого причины... Это полный код?


 
Digitman   (2003-09-23 16:48) [3]

а с какого боку здесь ShareMem ? даже и пробовать не буду ... никаким боком не касается ... проблема останется, 100%-но уверен


 
Digitman   (2003-09-23 16:51) [4]


> Владислав


можно сказать - да, полный ... ибо проверено уже :

library MyDll;
uses Windows, Messages, SysUtils;
... [1]
begin
ExitCode := 1;
end;

есть ли [1], нет ли - картина не меняется никак


 
Ketmar   (2003-09-23 16:53) [5]

а я знаю, с какого боку? просто больше вообще ничего в голову не приходит %-)


 
Digitman   (2003-09-23 16:53) [6]


> Владислав


вижу что "бред") ... но желания и времени трассировать отказывающий код пока нет .. поэтому и спрашиваю - вероятно, есть уже у кого-то готовые соображения на этот счет


 
Digitman   (2003-09-23 16:55) [7]


> Ketmar


ну знаешь ли) .. это смахивает на "а Вы их дустом непробовали ?")

неспортивно, сударь, неспортивно)))


 
Игорь Шевченко   (2003-09-23 16:58) [8]

Дополнение:
На NT 4 с той же версией Delphi ситуация аналогичная.
При загрузке DLL выдается честное сообщение: "Ошибка иницализации DLL, производится аварийное завершение процесса", а следом за ним идет AV по адресу в VCL50.BPL


 
Ketmar   (2003-09-23 16:59) [9]

>Digitman © (23.09.03 16:55) [7]
а я сегодня тормоз больше, чем обычно %-)


 
Ketmar   (2003-09-23 17:00) [10]

а если SysUtils выкинуть?


 
Digitman   (2003-09-23 17:00) [11]

оч похоже на то, что при RTP выгружаются раньше чем происходит обращение к DllEntryPoint(DLL_PROCESS_DETACH)


 
Игорь Шевченко   (2003-09-23 17:00) [12]

Более детальная диагностика показывает, что испорчен стек :))


 
Digitman   (2003-09-23 17:04) [13]


> Ketmar


нет, SysUtils тоже ни при чем


 
Игорь Шевченко   (2003-09-23 17:05) [14]

Первое исключение встречается в
Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=010f0000 ebx=00fe0838 ecx=0012f238 edx=00000000 esi=4015f03c edi=4015f040
eip=4000890a esp=0012f200 ebp=0012f220 iopl=0 nv up ei pl zr na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=0038 gs=0000 efl=00010246
*** WARNING: Unable to verify checksum for C:\WINNT\System32\Vcl50.bpl
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\WINNT\System32\Vcl50.bpl -
Vcl50!System+8e:
4000890a ff5304 call dword ptr [ebx+0x4] ds:0023:00fe083c=????????


 
Digitman   (2003-09-23 17:11) [15]


> Ketmar


да уж)... на медленный газ ты сегодня тем паче не тянешь)


 
Игорь Шевченко   (2003-09-23 17:15) [16]

Еще информация: call stack

WARNING: Stack unwind information not available. Following frames may be wrong.
Vcl50!System+0x8e
Vcl50!System+0x20
Vcl50!System+0xab
ntdll!LdrUnloadDll+0x315
ntdll!LdrQueryImageFileExecutionOptions+0x1616
ntdll!LdrLoadDll+0x16
kernel32!LoadLibraryExW+0x198
kernel32!LoadLibraryExA+0x5b
kernel32!LoadLibraryA+0xd
Vcl50!Stdctrls+0x71
Vcl50!Controls+0x124
Vcl50!Forms+0x3af
Vcl50!Controls+0x2f
Vcl50!Forms+0x1a


 
mrcat   (2003-09-23 17:17) [17]

может Application.CreateHandle перед ExitCode?


 
Думкин   (2003-09-23 17:18) [18]

У меня 6-й - здесь такого не наблюдаю.


 
Digitman   (2003-09-23 17:18) [19]


> Игорь Шевченко


похоже на то, что перехватчик искл-й потока (в SysInit) не подготовил стек к раскрутке ?


 
Digitman   (2003-09-23 17:21) [20]


> mrcat


какой Application ? не используется же модуль Forms


 
Digitman   (2003-09-23 17:22) [21]


> Думкин


уже что-то ...
а хост-приложение как собрано ? с RTP или без оных ?


 
Думкин   (2003-09-23 17:24) [22]

Гы. Вылезло - тоже самое, когда с RTP собрал.


 
Игорь Шевченко   (2003-09-23 17:27) [23]

Думкин © (23.09.03 17:24)

А, "...... мать", сказали сибирские мужики, после того, как положили лом в американскую лесопилку :))


 
Digitman   (2003-09-23 17:28) [24]


> Думкин


о как !

и Игорь тоже те же грабли поймал ... но на Д5 опять же ...


 
Думкин   (2003-09-23 17:28) [25]

Вылетает только если оба собраны с RTP.


 
Digitman   (2003-09-23 17:34) [26]


> Думкин


> Вылетает только если оба собраны с RTP

ну практически так же и у меня

за исключением "run time error 217" при завершении хост-приложения ... ну это - из другой оперы, не суть как важно


 
Игорь Шевченко   (2003-09-23 17:35) [27]

Ошибка происходит вот тут:
system.pas

procedure NotifyModuleUnload(HInstance: LongWord);
var
P: PModuleUnloadRec;
begin
P := ModuleUnloadList;
while P <> nil do
begin
try
P.Proc(HInstance);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
except
// Make sure it doesn"t stop notifications
end;
P := P.Next;
end;
end;

procedure UnregisterModule(LibModule: PLibModule);
var
CurModule: PLibModule;
begin
try
NotifyModuleUnload(LibModule.Instance);
^^^^^^^^^^^ а отсюда она вызывается ^^^^^^^^^^^^^^^^^^^^^
finally
if LibModule = LibModuleList then
LibModuleList := LibModule.Next
else
......

А UnregisterModule вызывается из Halt0


 
clickmaker   (2003-09-23 17:48) [28]

А если DLL оформить так, AV не вылезает

library MyDLL;

uses SysUtils, Classes, Windows;

{$R *.RES}

procedure DLLMain(dwReason: cardinal);
begin
ExitCode := 1;
end;

begin
DLLProc := @DLLMain;
end.


 
Digitman   (2003-09-23 17:56) [29]


> clickmaker


потому что DllMain() не вызывается на этапе DLL_PROCESS_ATTACH

а при DLL_PROCESS_DETACH результат выполнения строчки ExitCode:=1 совершенно монопенисуален системе


 
clickmaker   (2003-09-23 18:02) [30]

> Digitman © (23.09.03 17:56) [29]

Честно говоря, смысл такого кода

begin
ExitCode := 1;
end.


непонятен. Разве что, ради спортивного интереса... :)


 
Игорь Шевченко   (2003-09-23 18:03) [31]

clickmaker © (23.09.03 18:02)

Отнюдь. Например, в некоторых случаях DLL не должна загружаться.
Просто убрана проверка на "некоторые случаи"


 
Юрий Федоров   (2003-09-23 20:09) [32]

>>Отнюдь. Например, в некоторых случаях DLL не должна загружаться.
А может быть в случае сборки обоих модулей с RTP просто поднять исключение вместо ExitCode:=1?
Мне кажется, оно может быть отловлено в host"е ...


 
Digitman   (2003-09-24 08:09) [33]


> Юрий Федоров


> Мне кажется, оно может быть отловлено в host"е ...


И что же делать хост-процессу в этом случае, если он - non-Delphi ? Он же понятия не имеет ни о каких Делфи-исключениях !


 
Alex Konshin   (2003-09-24 09:16) [34]

Кстати, не уверен. Механизм исключений поддерживается на уровне системы. Часто компиляторы изобретают свои механизмы исключений, но, по моему Delphi использует системный.


 
Alex Konshin   (2003-09-24 09:18) [35]

Хотя это надо поисследовать, а они там такого понаворотили... Еще и linux под ногами путается.


 
Игорь Шевченко   (2003-09-24 10:02) [36]

Alex Konshin © (24.09.03 09:16)

Угу, использует системный. Иначе бы Access Violation не перехватывался.

Юрий Федоров © (23.09.03 20:09)

В коране написано, что не очень хорошо возбуждать исключения в DLL и перехватывать их вне DLL. Но в любом случае будет возбуждаться исключение в загрузчике DLL, а чем это чревато, я, честно говоря, не знаю


 
Владислав   (2003-09-24 10:21) [37]

> clickmaker © (23.09.03 18:02) [30]

На этапе загрузки DLL нужно, так сказать, препарировать ее состояние. По какой то причине, библиотека не в состоянии это сделать (нет необходимых ресурсов, не найдены необходимые файлы и прочее). Что же, грузить ее? На кой? Приложение все равно работать не будет. Хуже того, может работать неправильно. (Естественно, что это: ExitCode := 1 происходит по какому то условию).

> Digitman ©

Я подобное "ловил", но только без RTP. Установлена D6. При загрузке библиотеки производилась ее инициализация. Если она не успешная, изменялся ExitCode. Отладочная информация записывалась в лог-файл (Использовался модуль SysUtils). В итоге та же AV. Та же Run time error. Компилируешь с отключенной записью в лог файл - все происходит на ура.


 
Игорь Шевченко   (2003-09-24 12:10) [38]

Владислав © (24.09.03 10:21)

И тому есть хорошее и доступное объяснение у Рихтера - на этапе инициализации DLL нельзя вызывать ряд функций :))



Страницы: 1 вся ветка

Форум: "Потрепаться";
Текущий архив: 2003.10.13;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.53 MB
Время: 0.008 c
7-40699
Номолос
2003-07-26 09:16
2003.10.13
Как получить список всех носителей информаци?


14-40653
DProg
2003-09-24 11:20
2003.10.13
Как просто и быстро передать список строк от прогр. к программе?


4-40734
likeanangel
2003-08-08 11:12
2003.10.13
Графический вывод на DC


3-40275
sash2
2003-09-24 09:30
2003.10.13
Как создать архив.


3-40302
glow
2003-09-19 12:11
2003.10.13
Параметрический запрос





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский