You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
В дампе видно, что библиотека Library загружена дважды — как в составе префикса, так и независимо.
И это нарушение инварианта. Предполагается, что библиотека Library загружается один раз — в составе префикса. А тут она загрузилась два раза — в составе префикса и через зависимость xxx. Если исходники main.ref и xxx.ref использовали функции библиотеки с побочным эффектом (например, файловый ввод/вывод или копилку), то было бы заметно, что загружены два независимых экземпляра Library.
Попытка объяснения
Модули в дампе перечислены в следующем порядке:
Library.dll
a\xxx.rasl-module
test2.exe
Получается, стал загружаться test2.exe, загрузчик увидел неразрешённую ссылку xxx. Приостановил загрузку test2.exe, нашёл и начал загружать xxx.rasl-module. Обнаружил неразрешённую ссылку на Library. Поскольку префикс ещё не загружен до конца, загрузчик в нём не нашёл внедрённый (incorporated) Library и продолжил поиски. На первом запуске Library не нашёлся и программа упала. На втором нашёлся Library.dll и загрузился.
Загрузчик модулей умеет разрешать циклические зависимости. Обходя рекурсивно загружаемые модули по ссылкам, он поддерживает стек недозагруженных модулей, в которых хранит структуру stat. Если вновь загруженный модуль имеет эквивалентную stat, с той, которая есть на стеке, модуль повторно не загружается. Вместо этого берётся указатель полузагруженного модуля.
Предлагаемое решение
Аналогичное поведение (см. абзац выше) нужно реализовать и для псевдонимов.
The text was updated successfully, but these errors were encountered:
Воспроизведение ошибки
Вот такой вот сценарий работы:
Создаём два файла
main.ref
иa\xxx.ref
. Первый содержит функциюGo
, которая вызываетXXX
, второй — определение функцииXXX
, R-модуль.Устанавливаем
RL_MODULE_PATH
на папкуa
и пытаемся запустить:Не находит библиотеку
Library
.Копируем библиотеку
Library.dll
в текущую папку и ещё раз запускаем:Всё работает.
Напишем программу со ссылкой на
xxx
, которая падает с дампом:В дампе видно, что библиотека
Library
загружена дважды — как в составе префикса, так и независимо.И это нарушение инварианта. Предполагается, что библиотека
Library
загружается один раз — в составе префикса. А тут она загрузилась два раза — в составе префикса и через зависимостьxxx
. Если исходникиmain.ref
иxxx.ref
использовали функции библиотеки с побочным эффектом (например, файловый ввод/вывод или копилку), то было бы заметно, что загружены два независимых экземпляраLibrary
.Попытка объяснения
Модули в дампе перечислены в следующем порядке:
Library.dll
a\xxx.rasl-module
test2.exe
Получается, стал загружаться
test2.exe
, загрузчик увидел неразрешённую ссылкуxxx
. Приостановил загрузкуtest2.exe
, нашёл и начал загружатьxxx.rasl-module
. Обнаружил неразрешённую ссылку наLibrary
. Поскольку префикс ещё не загружен до конца, загрузчик в нём не нашёл внедрённый (incorporated)Library
и продолжил поиски. На первом запускеLibrary
не нашёлся и программа упала. На втором нашёлсяLibrary.dll
и загрузился.Загрузчик модулей умеет разрешать циклические зависимости. Обходя рекурсивно загружаемые модули по ссылкам, он поддерживает стек недозагруженных модулей, в которых хранит структуру
stat
. Если вновь загруженный модуль имеет эквивалентнуюstat
, с той, которая есть на стеке, модуль повторно не загружается. Вместо этого берётся указатель полузагруженного модуля.Предлагаемое решение
Аналогичное поведение (см. абзац выше) нужно реализовать и для псевдонимов.
The text was updated successfully, but these errors were encountered: