Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling mxDestroyArray on mxArray objects returned from Matlab Compiler Runtime

We've been interfacing with a library created from the Matlab Compiler. Our problem is related to an array returned from the library.

Once we're finished with the array, we'd like to free the memory, however, doing this causes occasional segmentation faults.

Here is the Matlab library (bugtest.m)::

function x = bugtest(y)

x = y.^2;

Here is the command we used to build it (creating libbugtest.so, and libbugtest.h)::

mcc -v -W lib:libbugtest -T link:lib bugtest.m

Here is our C test program (bug_destroyarray.c)::

#include <stdio.h>
#include <stdlib.h>

#include "mclmcrrt.h"
#include "libbugtest.h"

#define TESTS 15000

int main(int argc, char **argv) 
{
    const char *opts[] = {"-nojvm", "-singleCompThread"};
    mclInitializeApplication(opts, 2);  
    libbugtestInitialize();

    mxArray *output;
    mxArray *input;
    double *data;
    bool result;
    int count;

    for (count = 0; count < TESTS; count++) {

        input = mxCreateDoubleMatrix(4, 1, mxREAL);
        data = mxGetPr(input); data[0] = 0.5; data[1] = 0.2; data[2] = 0.2; data[3] = 0.1;

        output = NULL;
        result = mlfBugtest(1, &output, input);
        if (result) {
            /* HERE IS THE PROBLEMATIC LINE */
            /*mxDestroyArray(output);*/
        }

        mxDestroyArray(input);
    }

    libbugtestTerminate();
    mclTerminateApplication();
}

Here is how we compile the C program (creating bug_destroyarray)::

mbuild -v bug_destroyarray.c libbugtest.so

We believe that mxDestroyArray(output) is problematic.

We run the following to test crashing:

  • On each of the 32 cluster nodes.
  • Run bug_destroyarray.
  • Monitor output for segmentation faults.

Roughly 10% of the time there is a crash. If this is independent across nodes then you might suppose it is crashing roughly 0.3% of the time.

When we take out that problematic line we are unable to cause it to crash.

However memory usage gradually increases when this line is not included.

From the research we've done, it seems we are not supposed to destroy the array returned, if not, how do we stop from leaking memory?

Thanks.

like image 918
user2427155 Avatar asked May 28 '13 05:05

user2427155


1 Answers

Okay, I know this is a little old now, but in case it helps clarify things for anyone passing by ...

Amro provides the most pertinent information, but to expand upon it, IF you don't call the mxDestroyArray function as things stand, then you WILL leak memory, because you've set output to NULL and so the mlf function won't try to call mxDestroyArray. The corollary of this is that if you've called mxDestroyArray AND then try to call the mlf function AND output is NOT NULL, then the mlf function WILL try to call mxDestroyArray on output. The question then is to what does output point? It's a bit of a dark corner what happens to output after passing it to mxDestroyArray. I'd say it's an unwarranted assumption that it's set to NULL; it's certainly not documented that mxDestroyArray sets its argument to NULL. Therefore, I suspect what is happening is that in between your call to mxDestroyArray and the code re-executing the mlf function, something else has been allocated the memory pointed to by output and so your mlf function tries to free memory belonging to something else. Voila, seg fault. And of course this will only happen if that memory has been reallocated. Sometimes you'll get lucky, sometimes not.

The golden rule is if you're calling mxDestroyArray yourself for something that is going to be re-used, set the pointer to NULL immediately afterwards. You only really need to destroy stuff at the end of your function anyway, because you can safely re-use output variables in mlf calls.

Guy

like image 84
doctorG Avatar answered Sep 30 '22 01:09

doctorG