2
$\begingroup$

I am using CreateLibrary to create a dynamic library of a Mathematica function, so that it can be linked into standalone code, but I run into segmentation faults (after repeated calls) in WolframLibraryData.

The Mathematica function looks something like:

func = {E1 S1, E7 (-(S2/10) - 6 S7) + E8 (-(S2/10) - 6 S7) + 
  E2 ((6 S2)/5 + 12 S7), 4 E3 S3 - 2 E4 S3, -2 E3 S3 + 4 E4 S3, 
 4 E5 S4 - 2 E6 S4, -2 E5 S4 + 4 E6 S4, 
 E2 (-(S2/10) - 6 S7) + E8 (-(S2/30) + 2 S7) + E7 ((2 S2)/15 + 4 S7), 
 E2 (-(S2/10) - 6 S7) + E7 (-(S2/30) + 2 S7) + E8 ((2 S2)/15 + 4 S7)};

sigcomp = Compile[{{s, _Real, 1}, {e, _Real, 1}},
  Block[{S1, S2, S3, S4, S7, E1, E2, E3, E4, E5, E6, E7, E8},
   S1 = s[[1]];
   S2 = s[[2]];
   S3 = s[[3]];
   S4 = s[[4]];
   S7 = s[[6]];
   E1 = e[[1]];
   E2 = e[[2]];
   E3 = e[[3]];
   E4 = e[[4]];
   E5 = e[[5]];
   E6 = e[[6]];
   E7 = e[[7]];
   E8 = e[[8]];
   func
   ],
  CompilationOptions -> {"InlineExternalDefinitions" -> True}]

Then, with Export I create a .c-file. Another .c-file serves as the wrapper for this function and is based on the lowpassmainSrc code on https://reference.wolfram.com/language/CCodeGenerator/tutorial/Examples.html#333777088:

#include "sigcomp.h"
#include "WolframRTL.h"
#include "stdio.h"

int leafsig(double *s, double *e, double *csig)
{
    WolframLibraryData libData = 0;

    int err = 0;

    WolframLibraryData libData = WolframLibraryData_new(WolframLibraryVersion);

    Initialize_sigcomp(libData);

    MTensor s_in;
    MTensor e_in;
    MTensor sig_out;

    mint nconst = 6;
    mint nsig = 8;
    mint i;

    err = libData->MTensor_new( MType_Real, 1, &nconst, &s_in);
    if(err) return 1;
    err = libData->MTensor_new( MType_Real, 1, &nsig, &e_in);
    if(err) return 1;
    err = libData->MTensor_new( MType_Real, 1, &nsig, &sig_out);
    if(err) return 1;

    // put input into MMA tensors
    for (i = 1; i <= nconst; i++){
        libData->MTensor_setReal(s_in,&i,s[i-1]);   
    }

    for (i = 1; i <= nsig; i++){
        libData->MTensor_setReal(e_in,&i,e[i-1]);   
    }

    // run MMA function
    err = sigcomp(libData, s_in, e_in, &sig_out);
    if(err) return err;

    for (i = 1; i <= nsig; i++){
        libData->MTensor_getReal(sig_out,&i,&csig[i-1]);
    }

    libData->MTensor_free(s_in);
    libData->MTensor_free(e_in);
    libData->MTensor_free(sig_out);

    WolframLibraryData_free(libData);
    Uninitialize_sigcomp(libData);

    return 0;

}

These two files and the WolframRTL_Static_Minimal library are compiled into a library (.dylib, macOS 10.13) with CreateLibrary. This works without errors. The library can be included in my standalone code and produces expected results. After repeated calls, though, there is a segmentation fault, which according to valgrind seems to originate from the line

WolframLibraryData libData = WolframLibraryData_new(WolframLibraryVersion);

Valgrind says

==98098== 1 errors in context 1 of 132:
==98098== Invalid read of size 8
==98098==    at 0x1001F9E6C: RandomState_fromSpecification (randomgenerator.cpp:451)
==98098==    by 0x1001FA5AD: init_rtl_randomgenerator(int) (randomgenerator.cpp:739)
==98098==    by 0x1001F897C: InitRandom(int) (init_random.cpp:21)
==98098==    by 0x100187AB3: InitializeRuntimeLibrary (initialize.cpp:28)
==98098==    by 0x100182038: WolframLibraryData_new (WolframRTL.cpp:37)
==98098==    by 0x1000BA82F: leafsig (in /Users/mn/Documents/research/num-model/c/libleafsig.dylib)
==98098==    by 0x100000E7F: main (main.c:15)
==98098==  Address 0x54485254 is not stack'd, malloc'd or (recently) free'd
==98098== 
==98098== 
==98098== 1 errors in context 2 of 132:
==98098== Use of uninitialised value of size 8
==98098==    at 0x102AA0A0B: pthread_getspecific (in /usr/lib/system/libsystem_pthread.dylib)
==98098==    by 0x1001FA5AD: init_rtl_randomgenerator(int) (randomgenerator.cpp:739)
==98098==    by 0x1001F897C: InitRandom(int) (init_random.cpp:21)
==98098==    by 0x100187AB3: InitializeRuntimeLibrary (initialize.cpp:28)
==98098==    by 0x100182038: WolframLibraryData_new (WolframRTL.cpp:37)
==98098==    by 0x1000BA82F: leafsig (in /Users/mn/Documents/research/num-model/c/libleafsig.dylib)
==98098==    by 0x100000E7F: main (main.c:15)
==98098==  Uninitialised value was created by a heap allocation
==98098==    at 0x1000AC086: malloc (in /usr/local/Cellar/valgrind/3.14.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==98098==    by 0x1001F880C: New_KThreadLocalStorage (os-thread.cpp:352)
==98098==    by 0x1001F932A: RandomGeneratorMethod_add (randomgenerator.cpp:220)
==98098==    by 0x1001F8983: InitRandom(int) (init_random.cpp:22)
==98098==    by 0x100187A4F: InitializeRuntimeLibrary (initialize.cpp:28)
==98098==    by 0x100182038: WolframLibraryData_new (WolframRTL.cpp:37)
==98098==    by 0x1000BA82F: leafsig (in /Users/mn/Documents/research/num-model/c/libleafsig.dylib)
==98098==    by 0x100000E7F: main (main.c:15)

Am I doing something wrong or is there a problem with the Wolfram runtime library?

$\endgroup$
1
$\begingroup$

It appears that the line

WolframLibraryData_free(libData);

in my wrapper c-file causes this problem. Removing it solves the segmentation fault happening after repeated calls. The line shouldn't have been there in the first place; it's not there in the Wolfram.com CCodeGenerator tutorial I linked to, either.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.