crashshared-librariesddmd

Same code won't work (kind of) in a shared library, but works when used directly in the program


I created a scripting language, when it worked perfectly, I put all the code in a shared library, and made a wrapper for it, but the same code won't work in the shared library. I've noticed that the code runs faster in the shared library, but it always crashes, due to memory problems, saying that the index is out of array length, but the very same code runs outside the library perfectly.
I've also noticed that if I reduce the amount of work it has to do, it lasts a bit longer before crashing.

My question here is that what is causing this crash, and how do I stop it from happening?

P.S: I haven't included all code, because the whole code is of 1039 lines (but if you need the code to solve the problem, then I could link to it), but I have tracked the crash to a function. And the confusing this is, that function always crashes on the 821st time it's called, never before, that's for a more optimized code, when the code was not optimized, and used more CPU, it would crash at 702.

Plus: I'm using DMD2, and the functions are exported using extern(C), And I'm testing all this on a Linux system, Ubuntu 14.04. And this is how I compile the library:

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

And is loaded using the dlopen function.

Again if you missed my question: what is causing this crash, and how do I stop it from happening? EDIT: and how can I disable the garbage collector, gc.disable doesn't work, gc is undefined.

EDIT: I have tracked 'why' the crash is occurring, I put up debug code all over the files, just to find out that the garbage collector is messing with the script file that was loaded in the memory. I 'fixed' the problem, not actually, by adding a check. It checks if the script is not 'alright', it reloads it into the memory. This is avoiding the crash, but the problem still exists. This changes the question to:
How can I disable the garbage collector> BTW, I tried gc.disable, but the DMD says that gc is undefined.


Solution

  • You must initialize the runtime when you load your shared library for the first time. To do so you need to add something like that to your library:

    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;
    }
    

    I really mean like that and not exactly that. Since we don't know how your scripting engine is used an init counter might also be valid:

    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;
    }
    

    Anyway you should get the idea. The GC was undefined because you don't initialize the low level D runtime.