Segmentation Fault When Calling mxGetProperty (not within a MEX routine)

I have a relatively simple function that attempts to read in a MATLAB object. I want to note that this is NOT in a MEX routine. It is just a standalone C++ program that is meant to read the output of a MATLAB routine. Here is the relevant code snippet:
void LoadFromMatlabFile(const string& filename) {
MATFile* pmat = matOpen(filename.c_str(), "r");
if (pmat == NULL) {
LOG(ERROR) << "Error Opening MAT File: " << filename;
return;
}
// Should only have one entry.
const char* name = NULL;
mxArray* pa = matGetNextVariable(pmat, &name);
// Get the "level" data.
mxArray* levels = mxGetProperty(pa, 0, "level");
...
The pointer pa is valid and has the correct class name as verified via the method mxGetClassName.
So the problem is that if I call this routine with a mat file that contains just one MATLAB object (that itself contains a single property named level), I receive a segmentation fault. The fault itself happens in the routine mxUnshareEx, which has no documentation anywhere that I can find. Here is the backtrace:
#0 0x00007ffff71a0a21 in mxUnshareEx () from /usr/local/MATLAB/R2011b/bin/glnxa64/libmx.so
#1 0x00007ffff7198539 in mxGetProperty_730 () from /usr/local/MATLAB/R2011b/bin/glnxa64/libmx.so
#2 0x0000000000404f65 in LoadFromMatlabFile (filename=...) at detector.cc:139
My assumption is that because the mxGetProperty routine allocates its own storage, for some reason, it is attempting to "unshare" shared memory it thinks that MATLAB owns, when in fact, since this is a standalone program, that is obviously not the case. Hence, it tries to access memory that does not exist and BOOM.
Anyone have any bright ideas on how to fix this?
I know there is a function someone wrote ( http://www.mathworks.com/matlabcentral/fileexchange/30672-mxgetpropertyptr-c-mex-function ) that probably would work, but I was hoping for something simpler.
FYI. My version is R2011b.
Cheers, Sean

Answers (2)

My mxGetPropertyPtr function will not work in a standalone program. It only works in mex routines because it needs mexCallMATLAB to get at the property pointer in a round about way at the MATLAB calling level. There is no way that I know of to get the property pointer in a standalone program.
For your case, internally it looks like mxGetProperty gets a shared data copy of the property first and then deep copies it via the undocumented mxUnshareEx function. I do know that some Windows versions of MATLAB have a bug in the mxGetProperty function that will return a non-NULL pointer (looks valid to the programmer) even though there is an out-of-memory condition and the returned pointer is not valid. I don't recall which MATLAB versions have this bug at the moment. How large is your object? What happens if you try mxDuplicateArray(pa)? Do you get a NULL pointer returned (indicating out-of-memory), or does it work, or does that crash also?
Side Rant: It would be NICE if TMW included an official mxGetPropertyPtr function in the API so that us programmers can effectively manage our own data! Alas, they don't.
Just as an FYI, I'm on Linux.
The object itself is rather small in MATLAB terms. The property in question (named "levels") is a struct containing a couple of fields of size 48x1 and one field of size 48x2112.
mxDuplicateArray worked without issue. I don't think it's an out of memory problem.
What do you think about my hypothesis about the shared memory "unsharing"?
Can you help me think of any other ways around this or other potential solutions?
Thanks for the input!
-Sean

3 Comments

Brute force workaround:
1) Open up a MATLAB Engine.
2) Copy the variable over to the Engine workspace.
3) Use engEvalString to get the property into a separate variable name in the Engine workspace.
4) Copy the extracted property back to the standalone program
Ugly and inefficient, but maybe it will at least get you running until we can think of something better.
The MATLAB memory manager is doing all of the allocating, copying, etc for the API functions regardless of whether it is a mex routine or standalone. Creating shared data copies, deep copies, etc should simply work regardless of this (unless there is a bug in the API functions of course).
Yes for now I have just written a small MATLAB routine to throw the object into a struct actually, but I would much prefer to use the object directly. This is part of a distributed algorithm that was originally written by someone else and I would like to avoid having to mutate all of their outputs and instead just operate on them directly :(.
Let me know if you think/hear of anything else.
Is there someone I should contact at Mathworks about this? It seems like a pretty serious bug if it is indeed a bug.
-Sean
Get a small example put together that demonstrates the problem, then file a bug report. E.g., here:
Then click on the green bug "Report a Bug"

Sign in to comment.

Categories

Products

Tags

Asked:

on 12 Oct 2012

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!