insert new mexPrintf to stop Matlab crash

3 views (last 30 days)
Hello,
I'm encountering a very weird situation. My Matlab program crashed when I tried to run the mexw64 file and after modifier the c code by adding a mexPrintf("ok") line at the beginning and at the end, the program works. What could happen to my code?

Accepted Answer

Jane Jean
Jane Jean on 29 Mar 2012
#if !defined(_WIN32)
#define dgemm dgemm_
#endif
#include "mex.h"
#include "geometryMatrix64.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double *arrayLat, *arrayLong, *arraySeax, *arrayGm, *arrayTime, *arrayIncl, *arrayPeri;
double *A, *B, *C, *D, *E, *R1, *R3, *R_L, *v, *r; /* pointers to input & output matrices*/
double t_S, raan, anom;
int ind_s, ind_s_vis;
int i, j, outputRowLen, outputColLen;
size_t m,n,p,q; /* matrix dimensions */
/* form of op(A) & op(B) to use in matrix multiplication */
char *chn = "N";
/* scalar values to use in dgemm */
double one = 1.0, zero = 0.0;
arrayLat = mxGetPr(prhs[0]);
arrayLong = mxGetPr(prhs[1]);
arraySeax = mxGetPr(prhs[2]);
arrayGm = mxGetPr(prhs[3]);
arrayTime = mxGetPr(prhs[4]);
arrayIncl = mxGetPr(prhs[5]);
arrayPeri = mxGetPr(prhs[6]);
plhs[0] = mxCreateDoubleMatrix(m, n, mxREAL);
C = mxGetPr(plhs[0]);
for (i=0;i<outputRowLen;i++){
for(j=0; j<outputColLen; j++){
C[i*outputRowLen+j] = 0;
}
}
This is a very simple code with many entrees and Matlab returned me this
Error using geometryMatrix64
Out of memory. Type HELP MEMORY for your options.
Isn't that weird while all entrees are either scalar or 3by3 matrix? What could have happened ?
  3 Comments
Jane Jean
Jane Jean on 29 Mar 2012
Thanks. OMG. I keep making silly mistakes lately due to long working hours... Thank you very much!! ;p
Jan
Jan on 29 Mar 2012
It's time for a coffee break.

Sign in to comment.

More Answers (4)

James Tursa
James Tursa on 28 Mar 2012
Inserting mexPrintf calls changes the state of some internal register(s) and can have an effect on buggy code. E.g., I once saw a case where a function had an incorrect prototype. It really returned a 1-byte value but the prototype said it returned an int, so it was picking up 3 bytes of garbage on the return value. This garbage value was then used downstream for a size and it turned out to be huge and crashed MATLAB. However, by inserting a mexPrintf call just before this mis-prototyped function call things worked. It was because mexPrintf returned a 4-byte int, 3 bytes of which happened to be 0, effectively clearing out the garbage bytes in the return register before the mis-prototyped function call returned its 1 byte value.
Bottom line: Inserting seemingly unrelated printing code can have an effect on the output if your code has errors.
To see what is really going on in your code you will have to post it.
  2 Comments
Jane Jean
Jane Jean on 28 Mar 2012
I have experienced a couple of times that the compiled mexw64 is very unstable. The same code can be compiled and run without crash then somehow it doesn't work anymore. Why is Matlab behaving this way? Why isn't it as stable as normal c programming?
Jan
Jan on 28 Mar 2012
Dear Jane, mexw64 functions are unstable, if the programs contain bugs. Because C-mex functions are standard C-files compiled by standard C-compilers, their level of stability are exactly like all other C-files. This does not concern Matlab.
In opposite to Matlab, it is very easy to create invalid commands with a valid syntax.

Sign in to comment.


Jane Jean
Jane Jean on 28 Mar 2012
void matrixMultiplication(int rowA, int colA, int rowB, int colB, double *A, double *B, double *C){
/* C = A*B */
int m = rowA, n = colA, p = rowB, q = colB;
char *chn = "N";
double one = 1.0, zero = 0.0;
int i, lenC;
if (p!=m){
mexPrintf("Inner dimensions of matrix multiply do not match");
}
else {
dgemm(chn, chn, &m, &q, &n, &one, A, &m, B, &n, &zero, C, &m);
}
return;
}
And in the mexFunction:
/* Transformation into ECEF coordinate system */
A = mxMalloc(3*3*sizeof(double));
B = mxMalloc(3*3*sizeof(double));
C = mxMalloc(3*3*sizeof(double));
D = mxMalloc(3*3*sizeof(double));
E = mxMalloc(3*3*sizeof(double));
r = mxMalloc(3*1*sizeof(double));
if(A){
generateRotation3(-raan, A);
}
else{
mexPrintf("Memory allocation error 4.");
}
if(B){
generateRotation1(-arrayIncl[0], B);
}
else{
mexPrintf("Memory allocation error 5.");
}
if(C){
generateRotation3(-arrayPeri[0], C);
}
else{
mexPrintf("Memory allocation error 6.");
}
if(D){
//mexPrintf("entering matrix multiplication.............");
matrixMultiplication(3,3,3,3,A,B,D);
}
else{
mexPrintf("Memory allocation error 7.");
}
for(j=0; j<9; j++){
mexPrintf("A*B[%d] = %f\n",j,D[j] );
}
mxFree(A);
mxFree(B);
mxFree(C);
mxFree(D);
With mexPrintf, the execution works perfectly; without mexPrintf, Matlab crashes...
Thanks again James!! ;)
  3 Comments
Jane Jean
Jane Jean on 29 Mar 2012
Thank you very much. At least I have an idea now of what I can do/try. I'll change this right away.
Jane Jean
Jane Jean on 29 Mar 2012
The program crashed again. Posted some code below.

Sign in to comment.


Jane Jean
Jane Jean on 29 Mar 2012
void matrixMultiplication(mwSignedIndex rowA, mwSignedIndex colA, mwSignedIndex rowB, mwSignedIndex colB, double *A, double *B, double *C){
/* C = A*B */
mwSignedIndex m = rowA, n = colA, p = rowB, q = colB;
char *chn = "N";
double one = 1.0, zero = 0.0;
int i, lenC;
mexPrintf("Entering matrix multiplication...............\n");
if (p!=m){
mexPrintf("Inner dimensions of matrix multiply do not match");
}
else {
mexPrintf("Before dgemm...............\n");
dgemm(chn, chn, &m, &q, &n, &one, A, &m, B, &n, &zero, C, &m);
mexPrintf("After dgemm...............\n");
}
return;
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mxArray *inputLat, *inputLong, *inputIncl, *inputPeri, *inputSeax, *inputGm, *inputR_E, *inputEle_Mask, *inputTime, *inputTheta;
double *arrayLat, *arrayLong, *arrayIncl, *arrayPeri, *arraySeax, *arrayGm, *arrayR_E, *arrayEle_Mask, *arrayTime, *arrayTheta;
double *outputGeo,*outputGeo1,*outputGeo2;
double t_S = 0, *R_L, raan, anom, *r, *r_s, *r_x, *r_xs_ENU, ele, *Ang, *Dir, norm, *Geo;
double *A, *B , *C, *D, *E, *F, *v, a, b,c,d, sum = 0.0, *Id, *Geo_exp;
double *R1, *R3;
// intermediate matrix created for storing intermediate results of a single operation and freed once the entire operation is done
mwSignedIndex i, ind_s_vis =1, ind_s=0, ind, N_vis, k,j, outputRowLen, outputColLen, outputRowLen1, outputColLen1, outputRowLen2, outputColLen2;
VALUE_INDEX maxi_Ang;
The program still crashed... when I tried to call matrixMultiplication function within the mexFunction. I'm again left with no idea...

Jan
Jan on 29 Mar 2012
Does it still crash, if you comment out the dgemm call? You can allocate C much larger than required using mxCalloc and check if any non-zeros appear after the multiplication. Perhaps you confused the leading and trailing dimensions of one of the matrices. The Matlab->C->Fortran convetion conversion is not trivial, although it actually is.
  1 Comment
Jane Jean
Jane Jean on 29 Mar 2012
By commenting out the dgemm call, the program worked well at first then crashed after some time. I have then decided to keep to the matrixMultiply.c example. However, I've discover again a weird thing in mexFunction.
I shall paste the code below.

Sign in to comment.

Categories

Find more on Write C Functions Callable from MATLAB (MEX Files) in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!