Search code examples
matlabexceptionvisual-c++mexpdb-files

No Symbols Loaded: libmex.pdb not loaded (throw_segv_longjmp_seh_filter() = EXCEPTION_CONTINUE_SEARCH : C++ exception)


In order to create a MEX function and use it in my MATLAB code, like this:

[pow,index] = mx_minimum_power(A11,A12,A13,A22,A23,A33);  

I've created the file mx_minimum_power.cpp and written the following code in it:

#include <math.h>
#include <complex>
#include "mex.h"
#include "matrix.h"
#include "cvm.h"
#include "blas.h"
#include "cfun.h"

using std::complex;
using namespace cvm;

/* The gateway function */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    const int arraysize = 62172;
    const int matrixDimention = 3;
    float *inMatrixA11 = (float *)mxGetPr(prhs[0]);
    complex<float> *inMatrixA12 = (complex<float> *)mxGetPr(prhs[1]);
    complex<float> *inMatrixA13 = (complex<float> *)mxGetPr(prhs[2]);
    float *inMatrixA22 = (float *)mxGetPr(prhs[3]);
    complex<float> *inMatrixA23 = (complex<float> *)mxGetPr(prhs[4]);
    float *inMatrixA33 = (float *)mxGetPr(prhs[5]);
    basic_schmatrix< float, complex<float> > A(matrixDimention);
    int i = 0;
    for (i = 0; i < arraysize; i++)
    {
        A.set(1, 1, inMatrixA11[i]);
        A.set(1, 2, inMatrixA12[i]);
        A.set(1, 3, inMatrixA13[i]);
        A.set(2, 2, inMatrixA22[i]);
        A.set(2, 3, inMatrixA23[i]);
        A.set(3, 3, inMatrixA33[i]);
    }
}  

And then in order to be able to debug the code, I've created the mx_minimum_power.pdb and mx_minimum_power.mexw64 files, using the following code in the Matlab Command Window:

mex -g mx_minimum_power.cpp cvm_em64t_debug.lib  

The files blas.h, cfun.h, cvm.h and cvm_em64t_debug.lib are in the same directory as mx_minimum_power.cpp.
They are the headers and library files of the CVM Class Library.

Then I've attached MATLAB.exe to Visual Studio 2013, using the way explained here.
and have set a breakpoint at line40:

enter image description here

When I run my MATLAB code, there's no error until the specified line.

enter image description here

But if I click on the Step Over button, I'll encounter the following message:

enter image description here

With the following information added to the Output:

First-chance exception at 0x000007FEFCAE9E5D in MATLAB.exe: Microsoft C++ exception: cvm::cvmexception at memory location 0x0000000004022570.
> throw_segv_longjmp_seh_filter()
throw_segv_longjmp_seh_filter(): C++ exception
< throw_segv_longjmp_seh_filter() = EXCEPTION_CONTINUE_SEARCH  

enter image description here

Can you suggest me why libmex.pdb is needed at that line and how should I solve the issue?


If I stop debugging, I'll get the following information in MATLAB Command Window:

Unexpected Standard exception from MEX file.
What() is:First index value 0 is out of [1,4) range  

Right before pressing the step over button, we have the following values for A11[0],A12[0],A13[0],A22[0],A23[0],A33[0]:

enter image description here

that are just right as my expectations, according to what MATLAB passes to the MEX function:
enter image description here

Maybe the problem is because of wrong allocation for matrix A, it is as follows just before pressing the step over button.

enter image description here


Solution

  • The problem occurs because we have the following code in lines 48 to 53 of the cvm.h file:

    // 5.7 0-based indexing
    #if defined (CVM_ZERO_BASED)
    #   define CVM0 TINT_ZERO //!< Index base, 1  by default or 0 when \c CVM_ZERO_BASED is defined
    #else
    #   define CVM0 TINT_ONE  //!< Index base, 1  by default or 0 when \c CVM_ZERO_BASED is defined
    #endif  
    

    That makes CVM0 = 1 by default. So if we press the Step Into(F11) button at the specified line two times, we will get into line 34883 of the file cvm.h:

    basic_schmatrix& set(tint nRow, tint nCol, TC c) throw(cvmexception)
    {
        this->_set_at(nRow - CVM0, nCol - CVM0, c);
        return *this;
    }  
    

    Press Step Into(F11) at line this->_set_at(nRow - CVM0, nCol - CVM0, c); and you'll go to the definition of the function _set_at:

    // sets both elements to keep matrix hermitian, checks ranges
    // zero based
    void _set_at(tint nRow, tint nCol, TC val) throw(cvmexception)
    {
        _check_lt_ge(CVM_OUTOFRANGE_LTGE1, nRow, CVM0, this->msize() + CVM0);
        _check_lt_ge(CVM_OUTOFRANGE_LTGE2, nCol, CVM0, this->nsize() + CVM0);
        if (nRow == nCol && _abs(val.imag()) > basic_cvmMachMin<TR>()) { // only reals on main diagonal
            throw cvmexception(CVM_BREAKS_HERMITIANITY, "real number");
        }
        this->get()[this->ld() * nCol + nRow] = val;
        if (nRow != nCol) {
            this->get()[this->ld() * nRow + nCol] = _conjugate(val);
        }
    }
    

    pressing Step Over(F10) button,you'll get the result:

    enter image description here

    so in order to get nRow=1 and nCol=1 and not nRow=0 and nCol=0, which is out of the range [1,4), you should write that line of code as:

    A.set(2, 2, inMatrixA11[i]);