Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Segmentation violation in fortran source MEX file

30 views
Skip to first unread message

Sudarshan

unread,
Mar 25, 2013, 2:08:06 PM3/25/13
to
Hey guys,

I am new to MEX-ing and using an MEX function written by somebody else a long time back. I have gotten it to compile and link correctly. However, on execution of the main program, MATLAB crashes and i get an error saying that there was a "segmentation violation while the MEX file was running". I don't know what to do. Any help in this regard would be really awesome.

Below is the mexFunction i am working on:

subroutine mexFunction(nlhs, plhs, nrhs, prhs)
include 'thermo_LIBRARY.h'
include 'parameter.h'
integer plhs(*), prhs(*)! pointer to left-hand and right-hand side variables
integer nlhs, nrhs ! # of variables in plhs, prhs
integer mxCreateFull, mxGetString ! mx Functions declarations
integer mxGetM, mxGetN, mxIsNumeric, mxIsChar ! mx Functions declarations
integer m, n, size, status, alloc_err ! Dummy variables
integer Func_name_ptr ! Function name fortran pointers
character*100 Func_name ! Function name for fortran use
c ---------------------------------------------------Input fortran pointers
integer Input1_pr, Input2_pr, Input3_pr, Input4_pr, Input5_pr
integer Input6_pr, x_pr, y_pr, z_pr
c -------------------------------------------------- Output fortran pointers
integer Output1_pr, Output2_pr, Output3_pr, Output4_pr
integer Output5_pr, Output6_pr
c ----------------------------------------- Input arguments for fortran use
integer,allocatable, dimension (:) :: int_Input1, int_Input2
integer,allocatable, dimension (:) :: int_Input3, int_Input4
integer,allocatable, dimension (:) :: int_Input5, int_Input6
real*8,allocatable, dimension (:) :: real_Input1, real_Input2
real*8,allocatable, dimension (:) :: real_Input3, real_Input4
real*8,allocatable, dimension (:) :: real_Input5, real_Input6
integer Input1_sz,Input2_sz,Input3_sz,Input4_sz,Input5_sz,Input6_sz
c ---------------------------------------- Output arguments for fortran use
integer,allocatable, dimension (:) :: int_Output1, int_Output2,
&int_Output3, int_Output4, int_Output5, int_Output6
real*8,allocatable, dimension (:) :: real_Output1, real_Output2,
&real_Output3, real_Output4, real_Output5, real_Output6
integer Output1_sz,Output2_sz,Output3_sz,Output4_sz,Output5_sz,
&Output6_sz
real*8 x, y(3,3), z(3,3)
C ------------------------ Check for at least one function is requested
if (nrhs .lt. 1) then
call mexErrMsgTxt('Not a proper function selected. - [thermo_LIBRAR
&Y.dll]')
endif
if (mxIsChar(prhs(1)) .ne. 1) then
call mexErrMsgTxt('Function name parameter must be a valid string.
&- [thermo_LIBRARY.dll]')
endif
m = mxGetM(prhs(1))
n = mxGetN(prhs(1))
if (m .ne. 1) then
call mexErrMsgTxt('Function name parameter must be a row vector. -
&[thermo_LIBRARY.dll]')
endif
C ----------------------------------------- Call the requested function
C Get the string contents (dereference the input integer).
status = mxGetString(prhs(1),Func_name, 100)
C Check if mxGetString is successful
if (status .ne. 0) then
call mexErrMsgTxt('String length must be less than 100. - [thermo_LI
&BRARY.dll]')
endif
c ------------------------------------- ! Call initialization function
if (Func_name.eq.'init') then
status = 1
if (nrhs .ne. 2) then
call mexErrMsgTxt('One input (number of components) is required for
&the initialization - (init) [thermo_LIBRARY.dll]')
endif
if (mxIsNumeric(prhs(2)) .ne. 1) call mexErrMsgTxt('Input #1 is not
&a numeric. - (init) [thermo_LIBRARY]')
m = mxGetM(prhs(2))
n = mxGetN(prhs(2))
if (n .ne. 1 .or. m .ne. 1) call mexErrMsgTxt('Input #1 is not a sc
&alar. - &(density) [thermo_LIBRARY.dll]')
m = mxGetM(prhs(3))
n = mxGetN(prhs(3))
Input2_sz = m*n
if (n .ne. 1 .or. m .ne. 1) call mexErrMsgTxt('Input #2 is not a sc
&alar. - &(density) [thermo_LIBRARY.dll]')
m = mxGetM(prhs(4))
n = mxGetN(prhs(4))
Input3_sz = m*n
if (n .ne. nj .or. m .ne. 1) call mexErrMsgTxt('Input #3 is not
&a NC-element &row vector. - (density) [thermo_LIBRARY.dll]')
Input1_pr = mxGetPr(prhs(2))
Input2_pr = mxGetPr(prhs(3))
Input3_pr = mxGetPr(prhs(4))
plhs(1) = mxCreateFull(1,1,0)
plhs(2) = mxCreateFull(1,1,0)
Output1_pr = mxGetPr(plhs(1))
Output2_pr = mxGetPr(plhs(2))
status = 0
allocate (real_Input1(1),STAT = alloc_err)
status = status + alloc_err
allocate (real_Input2(1),STAT = alloc_err)
sta = status + alloc_e tus rr
allocate (real_Input3(nj),STAT = alloc_err)
status = status + alloc_err
allocate (real_Output1(1),STAT = alloc_err)
status = status + alloc_err
allocate (real_Output2(1),STAT = alloc_err)
status = status + alloc_err
if (status .ne. 0) then
if (allocated(real_Input1)) deallocate(real_Input1)
if (allocated(real_Input2)) deallocate(real_Input2)
if (allocated(real_Input3)) deallocate(real_Input3)
if (allocated(real_Output1)) deallocate(real_Output1)
if (allocated(real_Output2)) deallocate(real_Output2)
call mexErrMsgTxt('Memory allocation error. - (density) &[thermo_LI
&BRARY.dll]')
endif
call mxCopyPtrToReal8(Input1_pr,real_Input1,Input1_sz)
call mxCopyPtrToReal8(Input2_pr,real_Input2,Input2_sz)
call mxCopyPtrToReal8(Input3_pr,real_Input3,Input3_sz)
c subroutine pr_dens(real_Input1, real_Input2, real_Input3, real_Output1, real_Output2)
call mxCopyReal8ToPtr(real_Output1,Output1_pr, 1)
call mxCopyReal8ToPtr(real_Output2,Output2_pr, 1)
c ----------------------------------- ! Call equilibrium function
elseif ((Func_name.eq.'equilibrium') .and. (lib_Inited.eq.1)) then
if (nrhs .ne. 4) then
call mexErrMsgTxt('Three inputs (T, P, x) are required. - (equilibr
&ium)&[thermo_LIBRARY.dll]')
elseif (nlhs .ne. 2) then
call mexErrMsgTxt('Two outputs (T and vapor comp) are required.
& - (equilibrium) [thermo_LIBRARY.dll]')
endif
if (mxIsNumeric(prhs(2)) .ne. 1) call mexErrMsgTxt('Input #1 is not
&a numeric. - (equilibrium) [thermo_LIBRARY.dll]')
if (mxIsNumeric(prhs(3)) .ne. 1) call mexErrMsgTxt('Input #2 is not
&a numeric. - (equilibrium) [thermo_LIBRARY.dll]')
if (mxIsNumeric(prhs(4)) .ne. 1) call mexErrMsgTxt('Input #3 is not
&a numeric. - (equilibrium) [thermo_LIBRARY.dll]')
m = mxGetM(prhs(2))
n = mxGetN(prhs(2))
Input1_sz = m*n;
if (n .ne. 1 .or. m .ne. 1) call mexErrMsgTxt('Input #1 is not a sc
&alar. - &(equilibrium) [thermo_LIBRARY.dll]')
m = mxGetM(prhs(3))
n = mxGetN(prhs(3))
Input2_sz = m*n;
if (n .ne. 1 .or. m .ne. 1) call mexErrMsgTxt('Input #2 is not a sc
&alar. - &(equilibrium) [thermo_LIBRARY.dll]')
m = mxGetM(prhs(4))
n = mxGetN(prhs(4))
Input3_sz = m*n;
if (n .ne. 1 .or. m .ne. 1) call mexErrMsgTxt('Input #3 is not a NC
&Element row vector. - (equilibrium) &[thermo_LIBRARY.dll]')
Input1_pr = mxGetPr(prhs(2))
Input2_pr = mxGetPr(prhs(3))
Input3_pr = mxGetPr(prhs(4))
plhs(1) = mxCreateFull(1,1,0)
plhs(2) = mxCreateFull(1,nj,0)
Output1_pr = mxGetPr(plhs(1))
Output2_pr = mxGetPr(plhs(2))
status = 0
allocate (real_Input1(1),STAT = alloc_err)
status = status + alloc_err
allocate (real_Input2(1),STAT = alloc_err)
status = status + alloc_err
allocate (real_Input3(nj),STAT = alloc_err)
status = status + alloc_err
allocate (real_Output1(1),STAT = alloc_err)
status = status + alloc_err
allocate (real_Output2(nj),STAT = alloc_err)
status = status + alloc_err
if (status .ne. 0) then
if (allocated(real_Input1)) deallocate(real_Input1)
if (allocated(real_Input2)) deallocate(real_Input2)
if (allocated(real_Input3)) deallocate(real_Input3)
if (allocated(real_Output1)) deallocate(real_Output1)
if (allocated(real_Output2)) deallocate(real_Output2)
call mexErrMsgTxt('Memory allocation error. - (equilibrium) &[thermo
&_LIBRARY.dll]')
endif
call mxCopyPtrToReal8(Input1_pr,real_Input1,Input1_sz)
call mxCopyPtrToReal8(Input2_pr,real_Input2,Input2_sz)
call mxCopyPtrToReal8(Input3_pr,real_Input3,Input3_sz)
c subroutine pr_equil(t,p,x,yy) ' t is also an output
call pr_equil(real_Input1, real_Input2, real_Input3, real_Output1,
&real_Output2)
real_Output1 = real_Input1
call mxCopyReal8ToPtr(real_Output1,Output1_pr, 1)
call mxCopyReal8ToPtr(real_Output2,Output2_pr, nj)
c -------------------------------------------- ! No relevant function
else
call mexErrMsgTxt('Library is not initialized or No relevant functi
&on is &requested. - [thermo_LIBRARY.dll]')
endif
c -------------------------------------------- ! Memory deallocation
if (allocated(real_Input1)) deallocate(real_Input1)
if (allocated(real_Input2)) deallocate(real_Input2)
if (allocated(real_Input3)) deallocate(real_Input3)
if (allocated(real_Input4)) deallocate(real_Input4)
if (allocated(real_Input5)) deallocate(real_Input5)
if (allocated(real_Input6)) deallocate(real_Input6)
if (allocated(int_Input1)) deallocate(int_Input1)
if (allocated(int_Input2)) deallocate(int_Input2)
if (allocated(int_Input3)) deallocate(int_Input3)
if (allocated(int_Input4)) deallocate(int_Input4)
if (allocated(int_Input5)) deallocate(int_Input5)
if (allocated(int_Input6)) deallocate(int_Input6)
if (allocated(real_Output1)) deallocate(real_Output1)
if (allocated(real_Output2)) deallocate(real_Output2)
if (allocated(real_Output3)) deallocate(real_Output3)
if (allocated(real_Output4)) deallocate(real_Output4)
if (allocated(real_Output5)) deallocate(real_Output5)
if (allocated(real_Output6)) deallocate(real_Output6)
if (allocated(int_Output1)) deallocate(int_Output1)
if (allocated(int_Output2)) deallocate(int_Output2)
if (allocated(int_Output3)) deallocate(int_Output3)
if (allocated(int_Output4)) deallocate(int_Output4)
if (allocated(int_Output5)) deallocate(int_Output5)
if (allocated(int_Output6)) deallocate(int_Output6)
return
end

James Tursa

unread,
Mar 25, 2013, 5:20:21 PM3/25/13
to
"Sudarshan " <r.sudar...@gmail.com> wrote in message <kiq3q6$mfh$1...@newscl01ah.mathworks.com>...
> Hey guys,
>
> I am new to MEX-ing and using an MEX function written by somebody else a long time back. I have gotten it to compile and link correctly. However, on execution of the main program, MATLAB crashes and i get an error saying that there was a "segmentation violation while the MEX file was running". I don't know what to do. Any help in this regard would be really awesome.

(snip)

Are you running 32-bit or 64-bit?
What version of MATLAB are you using?

I see potential problems with your use of "integer" as a pointer (will need to be integer*8 on 64-bit systems ... i.e. should use mwPointer instead).

Also the mxCreateFull function is deprecated, and has been for quite some time, so this must be very old code.

Is it your intent to simply call the pr_equil function with MATLAB inputs & outputs? If so, this can probably be done much simpler.

James Tursa

Sudarshan

unread,
Mar 26, 2013, 12:56:18 AM3/26/13
to
> Are you running 32-bit or 64-bit?
> What version of MATLAB are you using?
>
> I see potential problems with your use of "integer" as a pointer (will need to be integer*8 on 64-bit systems ... i.e. should use mwPointer instead).
>
> Also the mxCreateFull function is deprecated, and has been for quite some time, so this must be very old code.
>
> Is it your intent to simply call the pr_equil function with MATLAB inputs & outputs? If so, this can probably be done much simpler.
>
> James Tursa

Hi James,

Thanks a lot for such a quick turnaround :) I am using Windows 7 32 bit, MATLAB R2011b 32 bit, Visual Studio 2010 Professional and Intel Visual Fortran Composer XE 2011. Yes the code is pretty old, written in 2001 and modified in 2006.

I have replaced mxCreateFull function with mxCreateDoubleMatrix. Also i used mwPointer wherever appropriate. However, MATLAB still crashes.

I guess i should learn about MEX files properly to get out of this. Anyway, if you think minor corrections could make the code work, would you please let me know?

The modified code is pasted below for your reference,

#include "fintrf.h"
C --------------------------------------------------------------------------
C MEX File Gateway implementation for Plant_Subroutines
C Date : 08-05-2001 by U?ur YILDIZ
C --------------------------------------------------------------------------

C Modified for gama-fi approach by ALMILA BAHAR Date:01/05/2006
C --------------------------------------------------------------------------
subroutine mexFunction(nlhs, plhs, nrhs, prhs)
include 'thermo_LIBRARY.h'
include 'parameter.h'
mwPointer plhs(*), prhs(*)! pointer to left-hand and right-hand side variables
integer nlhs, nrhs ! # of variables in plhs, prhs
mwPointer mxCreateDoubleMatrix, mxGetString, mxGetM, mxGetN ! mx Functions declarations
integer mxIsNumeric, mxIsChar, status, alloc_err ! mx Functions declarations
mwPointer m, n ! Dummy variables
mwSize size
mwPointer Func_name_ptr ! Function name fortran pointers
character*100 Func_name ! Function name for fortran use
c ---------------------------------------------------Input fortran pointers
mwPointer Input1_pr, Input2_pr, Input3_pr, Input4_pr, Input5_pr
mwPointer Input6_pr, x_pr, y_pr, z_pr
c -------------------------------------------------- Output fortran pointers
mwPointer Output1_pr, Output2_pr, Output3_pr, Output4_pr
mwPointer Output5_pr, Output6_pr
plhs(1) = mxCreateDoubleMatrix(1,1,0)
plhs(2) = mxCreateDoubleMatrix(1,1,0)
call mexErrMsgTxt('Two outputs (T and vapor comp) are required. (eq
&uilibrium) [thermo_LIBRARY.dll]')
endif
if (mxIsNumeric(prhs(2)) .ne. 1) call mexErrMsgTxt('Input #1 is not
&a numeric. - (equilibrium) [thermo_LIBRARY.dll]')
if (mxIsNumeric(prhs(3)) .ne. 1) call mexErrMsgTxt('Input #2 is not
&a numeric. - (equilibrium) [thermo_LIBRARY.dll]')
if (mxIsNumeric(prhs(4)) .ne. 1) call mexErrMsgTxt('Input #3 is not
&a numeric. - (equilibrium) [thermo_LIBRARY.dll]')
m = mxGetM(prhs(2))
n = mxGetN(prhs(2))
Input1_sz = m*n;
if (n .ne. 1 .or. m .ne. 1) call mexErrMsgTxt('Input #1 is not a sc
&alar. - &(equilibrium) [thermo_LIBRARY.dll]')
m = mxGetM(prhs(3))
n = mxGetN(prhs(3))
Input2_sz = m*n;
if (n .ne. 1 .or. m .ne. 1) call mexErrMsgTxt('Input #2 is not a sc
&alar. - (equilibrium) [thermo_LIBRARY.dll]')
m = mxGetM(prhs(4))
n = mxGetN(prhs(4))
Input3_sz = m*n;
if (n .ne. 1 .or. m .ne. 1) call mexErrMsgTxt('Input #3 is not a NC
&Element row vector. - (equilibrium) &[thermo_LIBRARY.dll]')
Input1_pr = mxGetPr(prhs(2))
Input2_pr = mxGetPr(prhs(3))
Input3_pr = mxGetPr(prhs(4))
plhs(1) = mxCreateDoubleMatrix(1,1,0)
plhs(2) = mxCreateDoubleMatrix(1,nj,0)
Output1_pr = mxGetPr(plhs(1))
Output2_pr = mxGetPr(plhs(2))
status = 0
allocate (real_Input1(1),STAT = alloc_err)
status = status + alloc_err
allocate (real_Input2(1),STAT = alloc_err)
status = status + alloc_err
allocate (real_Input3(nj),STAT = alloc_err)
status = status + alloc_err
allocate (real_Output1(1),STAT = alloc_err)
status = status + alloc_err
allocate (real_Output2(nj),STAT = alloc_err)
status = status + alloc_err
if (status .ne. 0) then
if (allocated(real_Input1)) deallocate(real_Input1)
if (allocated(real_Input2)) deallocate(real_Input2)
if (allocated(real_Input3)) deallocate(real_Input3)
if (allocated(real_Output1)) deallocate(real_Output1)
if (allocated(real_Output2)) deallocate(real_Output2)
call mexErrMsgTxt('Memory allocation error. - (equilibrium) [thermo

Steven_Lord

unread,
Mar 26, 2013, 10:21:56 AM3/26/13
to


"Sudarshan " <r.sudar...@gmail.com> wrote in message
news:kir9pi$dhr$1...@newscl01ah.mathworks.com...
>> Are you running 32-bit or 64-bit?
>> What version of MATLAB are you using?
>>
>> I see potential problems with your use of "integer" as a pointer (will
>> need to be integer*8 on 64-bit systems ... i.e. should use mwPointer
>> instead).
>>
>> Also the mxCreateFull function is deprecated, and has been for quite some
>> time, so this must be very old code.
>>
>> Is it your intent to simply call the pr_equil function with MATLAB inputs
>> & outputs? If so, this can probably be done much simpler.
>>
>> James Tursa
>
> Hi James,
>
> Thanks a lot for such a quick turnaround :) I am using Windows 7 32 bit,
> MATLAB R2011b 32 bit, Visual Studio 2010 Professional and Intel Visual
> Fortran Composer XE 2011. Yes the code is pretty old, written in 2001 and
> modified in 2006.
>
> I have replaced mxCreateFull function with mxCreateDoubleMatrix. Also i
> used mwPointer wherever appropriate. However, MATLAB still crashes.
> I guess i should learn about MEX files properly to get out of this.
> Anyway, if you think minor corrections could make the code work, would you
> please let me know?

*snip*

It might be a "minor correction" but that's a good chunk of code to dig
through to locate it. This reminds me of an old joke:

http://www.jokesplace.com/joke/retiredengineer.html

I recommend that you follow the suggestions in the Debugging MEX-files
section of the documentation:

http://www.mathworks.com/help/releases/R2011b/techdoc/matlab_external/f28378.html

If you don't have access to this online documentation, search the
documentation in your installation of MATLAB for "debug Fortran MEX" and it
should be one of the first few hits.

Alternately you could always go for the quick & dirty debugging method,
which involves doing divide and conquer in your file with mexPrintf
statements to isolate the line that's causing the crash. Write a mexPrintf
statement roughly in the middle of your file, run. If it crashes before the
message is printed, the line on which the crash occurs is in the first half
of your code; repeat by putting a mexPrintf in the middle of that first
half. Otherwise put a mexPrintf in the middle of the second half of your
code. Repeat this process until you know where the crash happens. Then you
get to work your way backwards and figure out why the crash occurs on that
line.

--
Steve Lord
sl...@mathworks.com
To contact Technical Support use the Contact Us link on
http://www.mathworks.com

Sudarshan

unread,
Mar 26, 2013, 4:19:14 PM3/26/13
to
"Steven_Lord" <sl...@mathworks.com> wrote in message <kisau4$ijv$1...@newscl01ah.mathworks.com>...
Haha, thats true Steve. Was worth a shot i guess :) I think ill go ahead and try the mexPrintf method. Anyway, i must compliment you guys on being so helpful despite having to manage such an active forum. Thanks :)

James Tursa

unread,
Mar 26, 2013, 8:19:06 PM3/26/13
to
"Sudarshan " <r.sudar...@gmail.com> wrote in message <kir9pi$dhr$1...@newscl01ah.mathworks.com>...
> > Are you running 32-bit or 64-bit?
> > What version of MATLAB are you using?
> >
> > I see potential problems with your use of "integer" as a pointer (will need to be integer*8 on 64-bit systems ... i.e. should use mwPointer instead).
> >
> > Also the mxCreateFull function is deprecated, and has been for quite some time, so this must be very old code.
> >
> > Is it your intent to simply call the pr_equil function with MATLAB inputs & outputs? If so, this can probably be done much simpler.
> >
> > James Tursa
>
> Hi James,
>
> Thanks a lot for such a quick turnaround :) I am using Windows 7 32 bit, MATLAB R2011b 32 bit, Visual Studio 2010 Professional and Intel Visual Fortran Composer XE 2011. Yes the code is pretty old, written in 2001 and modified in 2006.
>
> I have replaced mxCreateFull function with mxCreateDoubleMatrix. Also i used mwPointer wherever appropriate. However, MATLAB still crashes.
>
> I guess i should learn about MEX files properly to get out of this. Anyway, if you think minor corrections could make the code work, would you please let me know?
>
> The modified code is pasted below for your reference,

(snip)

I am not done trying to help you, but as Steven says it is a bit of code to work through. Forget the Fortran for the moment. If you could call the pr_equil function directly from MATLAB, what would that call look like? Also, can you post the Fortran interface details of this function? We may be able to greatly simplify this mex routine, particularly since the Intel compiler supports the %VAL() construct.

James Tursa
0 new messages