Тот же код не будет работать (вроде) в общей библиотеке, но работает при использовании непосредственно в программе
Я создал язык сценариев, когда он работал отлично, я поместил весь код в общую библиотеку и сделал для него оболочку, но тот же код не будет работать в общей библиотеке. Я заметил, что код работает быстрее в разделяемой библиотеке, но он всегда падает из-за проблем с памятью, говоря, что индекс не соответствует длине массива, но тот же самый код отлично работает вне библиотеки.
Я также заметил, что если я уменьшу объем работы, которую он должен выполнять, он длится немного дольше до сбоя.
Мой вопрос здесь заключается в том, что является причиной этого сбоя, и как я могу остановить его?
PS: я не включил весь код, потому что весь код состоит из 1039 строк (но если вам нужен код для решения проблемы, я мог бы сослаться на него), но я отследил сбой функции. И это сбивает с толку то, что функция всегда вылетает в 821-й раз, когда ее вызывают, никогда прежде, это для более оптимизированного кода, когда код не был оптимизирован и использует больше ресурсов ЦП, в 702 произойдет сбой.
Плюс: я использую DMD2, а функции экспортируются с помощью extern(C), и я тестирую все это в системе Linux, Ubuntu 14.04. И вот как я собираю библиотеку:
dmd -debug -gc "qscript.d" "qcompiler.d" "lists.d" "dllmain.d" "-shared" "-odobj/Debug" "-of/home/nafees/Desktop/Projects/QScr/QScr/bin/Debug/libQScr.so" -w -vcolumns
И загружается с помощью функции dlopen.
Опять же, если вы пропустили мой вопрос: что является причиной этого сбоя, и как я могу остановить его? РЕДАКТИРОВАТЬ: и как я могу отключить сборщик мусора, gc.disable не работает, gc не определена.
РЕДАКТИРОВАТЬ: я проследил "почему" происходит сбой, я поставил отладочный код во всех файлах, просто чтобы выяснить, что сборщик мусора портит файл сценария, который был загружен в память. Я "исправил" проблему, не добавляя чек. Он проверяет, если сценарий не "в порядке", он загружает его в память. Это позволяет избежать сбоя, но проблема все еще существует. Это меняет вопрос на:
Как я могу отключить сборщик мусора> Кстати, я пробовал gc.disable, но DMD говорит, что gc не определена.
2 ответа
Вы должны инициализировать среду выполнения при первой загрузке общей библиотеки. Для этого вам нужно добавить что-то подобное в вашу библиотеку:
private __gshared bool _init = false;
import core.runtime: rt_init, rt_term;
export extern(C) void init()
{
if (!_init) rt_init;
}
export extern(C) void terminate()
{
if (_init) rt_term;
_init = false;
}
Я действительно имею в виду это, а не совсем так. Поскольку мы не знаем, как используется ваш скрипт-движок, счетчик инициализации также может быть действительным:
private __gshared uint _init;
import core.runtime: rt_init, rt_term;
export extern(C) void init()
{
if (!_init) rt_init;
++init;
}
export extern(C) void terminate()
{
--init;
if (!_init) rt_term;
}
В любом случае, вы должны получить идею. GC был неопределен, потому что вы не инициализируете среду выполнения низкого уровня D.
Решил проблему сам. Как я уже сказал в редакторе Вопроса: я отследил проблему до сборщика мусора, сборщик мусора связывался с файлом сценария, который был загружен в память, что вызвало сбой библиотеки, поскольку сборщик мусора удалил содержимое сценария из память. Чтобы решить эту проблему, я добавил:
import core.memory;
...
GC.disable();
Это решило всю проблему.