Тот же код не будет работать (вроде) в общей библиотеке, но работает при использовании непосредственно в программе

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

Мой вопрос здесь заключается в том, что является причиной этого сбоя, и как я могу остановить его?

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();

Это решило всю проблему.

Другие вопросы по тегам