32-bit MEX file (Fortran) works correctly, the same 64-bit MEX file causes "Segmentation Fault"

2 views (last 30 days)
Hello everyone
I am working with a Fortran compiled MEX file in a Linux based 32-bit environment, and it works properly (*.mexglx file).
I need to work with that same code in a 64-bit environment, so I just re-compile the Fortran code in that machine, getting a *.mexa64 file. Well, this file gets a "Segmentation Fault". The Fortran code is the same, and Matlab did not complain when compiling with 'mex'.
The original code is just ordinary code, with some variable inputs and some variable outputs. It does not "interact" with anything else.
Does anyone know where the problem might be?
Thank you in advance.
Carlos
  4 Comments
Carlos Casanueva
Carlos Casanueva on 1 Jul 2011
@James Tursa
I'm not an expert on compilation, but if the code worked correctly for 32-bit, why should it be a coding issue? The original Fortran code is exactly the same. If you still think it could be some code-related issue I can post it here.
@Kaustubha Govind
I had some issues debugging, but finally I solved them, I will write a proper answer and not here in the comments.
Jan
Jan on 1 Jul 2011
@Carlos: It is really likly that there is a problem in the code. So please show us the relevant part of it.

Sign in to comment.

Answers (7)

Friedrich
Friedrich on 1 Jul 2011
You have to be carefull with simply recompile the Fortran code on 64bit. The FORTRAN pre-compiler interprets the mwPointer differnt. The FORTRAN preprocessor converts mwPointer to INTEGER*4 when building binary MEX-files on 32-bit platforms and to INTEGER*8 on 64-bit platforms. So make sure you are using mwSize instead of some hardcoded INTEGER*4.
Without any code its hard to tell whats causes this crash. Please post some code which crashes if you need further help with this.

Carlos Casanueva
Carlos Casanueva on 1 Jul 2011
I finally managed to debug the MEX file. First I add a breakpoint at line 1, then I start to debug.
The debugger stops at line 1 and already has the SIGSEV segmentation fault. Anyone knows why?
Then I continue debugging (no more breakpoints, it is the rest of the file) and the crash occurs.
(gdb) break fsimwear_rev5
Breakpoint 1 at 0x2aaaab50aaea: file fsimwear_rev5.f, line 1.
(gdb) continue
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x000000370407b59b in memcpy () from /lib64/libc.so.6
Continuing.
Unable to create crash dump log file
------------------------------------------------------------------------
Segmentation violation detected at Fri Jul 1 14:00:08 2011
------------------------------------------------------------------------
Configuration:
MATLAB Version: 7.7.0.471 (R2008b)
MATLAB License: 308809
Operating System: Linux 2.6.18-128.7.1.el5.pdc5noib #1 SMP Thu Sep 16 19:17:28 CEST 2010 x86_64
GNU C Library: 2.5 stable
Window System: No active display
Current Visual: None
Processor ID: x86 Family 6 Model 7 Stepping 6, GenuineIntel
Virtual Machine: Java is not enabled
Default Encoding: US-ASCII
Fault Count: 1
Register State:
rax = 0000000041f46840 rbx = 0000000000000000
rcx = 0000000000000800 rdx = 00000008000000d0
rbp = 0000000041f46a10 rsi = 0000000108363798
rdi = 0000000041f46840 rsp = 0000000041f46758
r8 = 00000000088240b0 r9 = 0000000000000000
r10 = 0000000000000000 r11 = 0000000000004000
r12 = 0000000000000001 r13 = 0000000000000001
r14 = 000000000897a300 r15 = 0000000041f47290
rip = 000000370407b59b flg = 0000000000010206
Stack Trace:
[0] libc.so.6:memcpy~(1, 0x088240b0, 0x127f00000000, 0x41f47298) + 347 bytes
[1] libmex.so:mexRunMexFile(1, 0x41f47290, 0x100000018, 0x41f471d0) + 108 bytes
[2] libmex.so:Mfh_mex::runMexFileWithSignalProtection(int, mxArray_tag**, int, mxArray_tag**)(0x41f47050, 0x41f46c50, 0x41f471d0, 0x08399ee0) + 137 bytes
[3] libmex.so:Mfh_mex::dispatch_file(int, mxArray_tag**, int, mxArray_tag**)(0x41f471d0, 0x0897a300, 0x0897a300, 0x41f47dd0) + 245 bytes
[4] libmwm_dispatcher.so:Mfh_file::dispatch_fh(int, mxArray_tag**, int, mxArray_tag**)(0x41f471c0, 1, 0x41f47100, 0x2b681483f380) + 297 bytes
[5] libmwm_interpreter.so:inDispatchFromStack(int, char const*, int, int)(0x41f475ac, 0x2a100000001, 0x087fb38c, 0x100000000) + 1062 bytes
[6] libmwm_interpreter.so:inDispatchCall(char const*, int, long, int, int*, int*)(0, 0x0821cbc0, 6, 0x41f475b0) + 165 bytes
[7] libmwm_interpreter.so:inInterp(inDebugCheck, int, int, opcodes, inPcodeNest_tag volatile*, long*)(0x41f47a58, 0x0821cba0, 0x100000000, 0x100000000) + 2931 bytes
[8] libmwm_interpreter.so:protected_inInterp(inDebugCheck, int, int, opcodes, inPcodeNest_tag*, long*)(0x0839a4a0, 0x07fa92d0, 0x0839a4a0, 0x6b9a72a2efb128) + 140 bytes
[9] libmwm_interpreter.so:inInterPcodeSJ(inDebugCheck, int, int, opcodes, inPcodeNest_tag*, long*)(0, 0x41f47a20, 0x41f47a6c, 0) + 265 bytes
[10] libmwm_interpreter.so:inExecuteMFunctionOrScript(Mfh_mp*, bool)(0, 0x3700000001, 0x41f47b40, 0x41f47c50) + 680 bytes
[11] libmwm_interpreter.so:inRunMfile(int, mxArray_tag**, int, mxArray_tag**, Mfh_mp*, inWorkSpace_tag*)(0x41f48b70, 0x0839a4a0, 0x0839a4a0, 0x41f48db0) + 666 bytes
[12] libmwm_dispatcher.so:Mfh_file::dispatch_fh(int, mxArray_tag**, int, mxArray_tag**)(0x41f47e70, 0, 0x41f48b70, 0x41f489b0) + 297 bytes
[13] libmwm_interpreter.so:inEvalPcodeHeaderToWord(_memory_context*, int, mxArray_tag**, _pcodeheader*, Mfh_mp*, unsigned int)(0x41f47e90, 0x41f48030, 0x41f48bc0, 0) + 187 bytes
[14] libmwm_interpreter.so:in_local_call_script_function(_memory_context*, _pcodeheader*, int, mxArray_tag**, unsigned int, bool)(0x41f48890, 0x41f4802c, 0x41f48a50, 0x41f48930) + 103 bytes
[15] libmwm_interpreter.so:inEvalStringWithIsVarFcn(_memory_context*, char const*, EvalType, int, mxArray_tag**, inDebugCheck, _pcodeheader*, int*, bool (*)(void*, char const*), void*, bool, bool)(0, 0, 0x2b68157a1960, 0) + 2593 bytes
[16] libmwm_interpreter.so:inEvalCmdWithLocalReturn(char const*, int*, bool, bool, bool (*)(void*, char const*))(0x41f48bd0, 0x08331bb0, 0x41f48d70, 0) + 149 bytes
[17] libmwbridge.so:evalCommandWithLongjmpSafety(char const*)(0, 0, 0, 0) + 94 bytes
[18] libmwbridge.so:mnParser(0x07be3fa0, 0x07be3f30, 0x07bdee60, 0x07bdee40) + 291 bytes
[19] libmwmcr.so:mcrInstance::mnParser()~(0x41f490bf, 0x41f490b0, 0x7fffffaad0d8, 0x241f48eb0) + 82 bytes
[20] MATLAB:mcrMain(int, char const**)(0x41f491c0, 0x41f49940, 0, 0x00a00000) + 493 bytes
[21] libmwmcr.so:0x00002b681542cc9c(0, 0x41f49940, 0, 0)
[22] libpthread.so.0:0x0000003704c06367(0x41f49940, 1, 0, 0xa99ba000008a0600)
This error was detected while a MEX-file was running. If the MEX-file
is not an official MathWorks function, please examine its source code
for errors. Please consult the External Interfaces Guide for information
on debugging MEX-files.

Carlos Casanueva
Carlos Casanueva on 1 Jul 2011
OK, thanks for your help. Here is the code with some mathematics removed:
subroutine fsimwear_rev5(dz,m,n,a,b,ffn,cx,cy,cz,upsx,upsy,phi,
& fric,V,k1,k2,k3,k4,kp_lim,kv_lim_low,
& kv_lim_high,H,ga,elastic,psimp,fricwear,
& D_wheel,dz_WLD,dA_PSH)
implicit none
integer m,n
real*8 dz(m,n),a,b,ffn,cx,cy,cz,upsx,upsy,phi,fric,V,k1,k2,k3,
& k4,kp_lim,kv_lim_low,kv_lim_high,H,ga,D_wheel,
& dz_WLD(m,n),dA_PSH
logical elastic,psimp,fricwear
integer j,k
real*8 x,y,dx,dxf,dy,t,xle,xx,yy
real*8 lx,ly,lz,uxl,uyl,uzl,vslipx,vslipy,vslip,s,kalle
real*8 f,ph_max,px,py,pz,pbound,para,q
real*8 fn,fx,fy,amz
real*8 fricwk,dfric,Tgamma_A(m,n),kfric,kfric_g
logical debug/.false./,forces/.false./
real*8 pi/3.14159265358979/,ro/7850/ ! pi, steel density
c Initiate variables
if (debug) then
print *, ' m=', m,' n=',n
print *, ' a=', a,' b=',b
print *, ' ffn=', ffn
print *, ' cx=', cx,' cy=', cy,' cz=', cz
print *, 'upsx=',upsx,' upsy=',upsy,' phi=', phi
print *, 'fric=',fric,' V=', V
print *, ' k1=', k1,' k2=', k2
print *, ' k3=', k3,' k4=', k4
end if
fn=ffn/fric
uxl=upsx/lx
uyl=upsy/ly
uzl=phi/lz
if (debug) print *, ' lx=', lx,' ly=', ly,' lz=', lz
if (debug) print *, ' uxl=', uxl,' uyl=', uyl,' uzl=',uzl
f=2*ffn/(pi*a*b)
if (.not.psimp) then
ph_max=1.5*fn/(pi*a*b)
end if
fx=0
dy=2*b/n
y=-b+dy/2
c
t=dx/V
if (debug) write(*,*) (t)
c --- Outer loop
if (debug) then
write(*,'(a)') ' '
write(*,'(a)') ' x y q '//
& ' fx fy fn'
end if
do 20 j=1,n
yy=(y/b)**2
xle=a*sqrt(1-yy)
c r3 x=a-dx/2
py=0
c --- Inner loop
if (debug) write(*,'(a)') ' '
do 10 k=1,m
c ---
if (abs(x).lt.xle) then
xx=(x/a)**2
dxf=xle-x ! r5 distance to front edge
if (dxf.lt.dx) then ! r5
px=px-(uxl-uzl*y)*dxf ! r5
py=py-(uyl+(uzl*(x+dxf)+uzl*x)/2)*dxf ! r5 Heun
else ! r5
px=px-(uxl-uzl*y)*dx
end if ! r5
para=1-yy-xx
pbound=f*para
if (debug) print *, 'px=',px,' py=',py
if (debug) print *, 'pbound=',pbound
q=sqrt(px**2+py**2+1e-20)/pbound
c Normal stress distribution
if (psimp) then ! Kalker's simplified
pz=pbound/fric
else ! Hertz
pz=ph_max*sqrt(para)
end if
c ---
if (q.gt.1) then
c Sliding velocity
if (elastic) then
vslipx=-V*lx*px*(1-1/q)/dx ! S
vslipy=-V*ly*py*(1-1/q)/dx ! eq. after 3.38b in
else
vslipy=V*(upsy+phi*x)
end if
vslip=sqrt(vslipx**2+vslipy**2)
c
c
px=px/q
py=py/q
c ---
if(pz.gt.kp_lim) then
kalle=k1
else
if(vslip.lt.kv_lim_high) then
if(vslip.lt.kv_lim_low) then
kalle=k2
end if
if(vslip.gt.kv_lim_low) then
kalle=k3
end if
else
kalle=k4
end if
end if
c
dz(j,k)=kalle*s*pz/H
c ---
else
dz(j,k)=0
end if ! slip zone
c ---
if (forces) then
fx=fx+px*dx*dy
amz=amz+(py*x-px*y)*dx*dy
end if ! r5
if (forces.or.fricwear) then ! r5 ! r5
c r5 fricwk=fricwk+((upsx-phi*y)*px+(upsy+phi*x)*py)*dx*dy
end if
c ---
if (fricwear) then
c r5 dfric=(dabs((upsx-phi*y)*px)+dabs((upsy+phi*x)*py))*dx*dy
Tgamma_A(j,k)=dabs(dfric)/(dx*dy)
c r5 fricwk=fricwk+dfric
if (Tgamma_A(j,k).lt.10.4E6) then
kfric=Tgamma_A(j,k)*5.3E-15
elseif (Tgamma_A(j,k).lt.77.2E6) then
else
kfric=Tgamma_A(j,k)*61.9*1E-15-4724*1E-9
end if
c
dz_WLD(j,k)=kfric*Tgamma_A(j,k)*dx/ro
end if
c ---
else
dz(j,k)=0
end if ! contact patch
x=x-dx
if (debug) then
write(*,'(1p7e13.5)') x, y, q, px*dx*dy, py*dx*dy,
& (1-yy-xx)*f, dx*dy
end if
if (debug) print *,'dz(',j,k,')=',dz(j,k)
10 continue ! inner loop
y=y+dy
20 continue ! outer loop
c ---
if (fricwear) then
c
if (fricwk.lt.100) then
elseif (fricwk.lt.200) then
kfric_g=25/(D_wheel*1000)
else
kfric_g=(1.19*fricwk-154)/(D_wheel*1000)
end if
c
dA_PSH=kfric_g*1E-6*pi*D_wheel/1000
end if
return
end
c =============================================================
subroutine mexFunction(nlhs,plhs,nrhs,prhs)
implicit none
integer plhs(*),prhs(*),alen,nlhs,nrhs
parameter(alen=26)
integer in_ptr,out_ptr,m,n,pflag,elflag,fricflag,
& mxGetPr,mxCreateDoubleMatrix,mxREAL
real*8 dz(100,100),a,b,ffn,cx,cy,cz,upsx,upsy,phi,fric,V,
& k1,k2,k3,k4,kp_lim,kv_lim_low,kv_lim_high,H,ga,
& D_wheel,dz_WLD(100,100),dA_PSH,fsin(alen)
logical psimp,elastic,fricwear
c Extract input data from pointer prhs
in_ptr=mxGetPr(prhs(1))
call mxCopyPtrToReal8(in_ptr, fsin, alen)
m=fsin(1)
n=fsin(2)
a=fsin(3)
b=fsin(4)
ffn=fsin(5)
cx=fsin(6)
cy=fsin(7)
cz=fsin(8)
upsx=fsin(9)
upsy=fsin(10)
phi=fsin(11)
fric=fsin(12)
V=fsin(13)
k1=fsin(14)
k2=fsin(15)
k3=fsin(16)
k4=fsin(17)
kp_lim=fsin(18)
kv_lim_low=fsin(19)
kv_lim_high=fsin(20)
H=fsin(21)
ga=fsin(22)
elflag=fsin(23)
elastic=.true.
if (elflag.eq.0) elastic=.false.
pflag=fsin(24)
psimp=.true.
if (pflag.eq.0) psimp=.false.
fricflag=fsin(25)
fricwear=.true.
if (fricflag.eq.0) fricwear=.false.
D_wheel=fsin(26)
c Call Fastsim
call fsimwear_rev5(dz,m,n,a,b,ffn,cx,cy,cz,upsx,upsy,phi,fric,V,
& k1,k2,k3, k4,kp_lim, kv_lim_low,kv_lim_high,H,
& ga,elastic,psimp,fricwear,D_wheel,dz_WLD,
& dA_PSH)
c Assign output arrays
plhs(1)=mxCreateDoubleMatrix(m,n,mxREAL)
out_ptr=mxGetPr(plhs(1))
call mxCopyReal8ToPtr(dz,out_ptr,m*n)
plhs(2)=mxCreateDoubleMatrix(m,n,mxREAL)
out_ptr=mxGetPr(plhs(2))
call mxCopyReal8ToPtr(dz_WLD,out_ptr,m*n)
plhs(3)=mxCreateDoubleMatrix(1,1,mxREAL)
out_ptr=mxGetPr(plhs(3))
call mxCopyReal8ToPtr(dA_PSH,out_ptr,1)
return
end
  1 Comment
Friedrich
Friedrich on 1 Jul 2011
i think for example this can be dangerous:
Extract input data from pointer prhs
in_ptr=mxGetPr(prhs(1))
call mxCopyPtrToReal8(in_ptr, fsin, alen)
Since in_ptr is an integer and not an mwPointer as it should arcording the documentation. Is this integer 32bit or 64bit in the compiled mex file? because when its 32bit it will crash since you call mxCopyPtrToReal8 on it which expects a 64bit variable. please modify your code that it matched the datatypes mentioned in the documentation.

Sign in to comment.


Jan
Jan on 1 Jul 2011
What exactly is "integer" in your 64bit compiler? nrhs and nlhs must be "integer*4" for example. If they are "integer*8", the mex should crash.
  1 Comment
James Tursa
James Tursa on 1 Jul 2011
A Fortran default integer is typically integer*4, even for 64-bit systems. It is likely that this is causing a pointer problem in the code.

Sign in to comment.


James Tursa
James Tursa on 1 Jul 2011
A Fortran default integer is almost certainly an integer*4, even for 64-bit compilers. Compiler vendors typically do this so that older code that depends on a default integer being an integer*4 have a better chance of compiling and running correctly when they use their code on a 64-bit machine. However, this makes a default integer type unreliable to use for holding a pointer, and using it that way will almost certainly crash MATLAB. This is the EXACT problem that I was expecting to see in the code and why one should always use mwPointer for the pointer types and mwSize for the size types. Your code needs to be completely scrubbed and everything made consistent with regards to the API interface. If you want to see examples of this you can take a look at my Fortran 95 - MATLAB API interface submission on the FEX:
That being said, I haven't completely updated this submission for 64-bit yet. I have all of the coding done but haven't completed testing yet. Hopefully I will be able to upload it in the next week or so.
Another reason to take a look at my Fortran 95 submission is that it has routines to get Fortran pointers to the mxArray contents, so you don't need to use the clunky mxCopyReal8ToPointer and mxCopyPointerToReal8 routines at all.

Carlos Casanueva
Carlos Casanueva on 21 Jul 2011
Thanks for your help. As I said before, my fortran knowledge is really basic and this code is inherited from a former worker, so I was quite lost. I will try to re-read all the mex file documentation and with the tips you gave me I guess I will repair it.
CC
  3 Comments
Carlos Casanueva
Carlos Casanueva on 2 Mar 2012
No, sorry, I am still working on this, but as James Tursa said, check his comments: that is what I am using to try to fix it.

Sign in to comment.


Helen
Helen on 29 Jul 2016
For more information, see Upgrade MEX-Files to Use 64-Bit API. In particular, see the section Update Fortran Source Code.

Categories

Find more on Fortran with MATLAB in Help Center and File Exchange

Products

Community Treasure Hunt

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

Start Hunting!