SIGSEGV error in mixed language code
I have a mostly Fortran code which I can compile successfully in Windows without any problems, however when I try to compile it on Linux I get a SIGSEGV error. The code contains a small portion written in C, and this is where the problems are caused. I did not write the code, and I have little experience with C, so I am having major issues fixing the error.
The section of the FORTRAN code (in uvss_in_lib.f) that is giving me problems is as follows:
subroutine uvss_lib(kneq,kncoeff,values,irow,icol,rhs,iflag)
include 'sord.inc'
dimension values(1),rhs(1)
dimension irow(1),icol(1)
INTEGER(KIND=INT_PTR_KIND()) :: i_kpt
pointer(i_kpt ,kpt(1))
INTEGER(KIND=INT_PTR_KIND()) :: i_maxa
pointer(i_maxa,maxa(1))
INTEGER(KIND=INT_PTR_KIND()) :: i_row2
pointer(i_row2,irow2(1))
INTEGER(KIND=INT_PTR_KIND()) :: i_values2
pointer(i_values2,values2(1))
if(iflag.eq.1) then
open(79,file='summary',status='scratch')
write(79,*) ' neq =',kneq
write(79,*) ' ncoeff =',kncoeff
endif
c if(iflag.eq.1) then
c write(79,*) '0- lic is fine ' ,kneq,kncoeff
c call send_file()
c endif
if(iflag.eq.1) then
i_maxa = mallocw((kneq+10)*nb,110)
i_kpt = mallocw((kneq+10)*nb,110)
i_values2 = mallocw((kncoeff+10)*nb,110)
i_row2 = mallocw((kncoeff+10)*nbi,110)
endif
call uvss_convert(kneq,kncoeff,values,irow,icol,rhs,maxa,
& irow2,values2,kpt,iflag)
if(iflag.eq.3) then
call free(i_maxa)
call free(i_kpt )
call free(i_values2 )
call free(i_row2 )
endif
return
end
subroutine uvss_convert(kneq,kncoeff,values,irow,icol,rhs,
& maxa,irow2,values2,kpt,iflag)
include 'sord.inc'
dimension values(1),rhs(1)
dimension irow(1),icol(1),maxa(1),kpt(1)
dimension values2(1),irow2(1)
do i = 1, kneq
kpt(i) = 0
enddo
...
...
...
return
end
where mallocw (mallocw.c) is C code:
#include
#include
#if defined (_CRAY) || defined (_WIN32)
# define mallocw MALLOCW
#else
#if !defined(_AIX) && !defined(__hpux)
# define mallocw mallocw_
#endif
#endif
void* mallocw(n,ii)
int *n;
int *ii;
{
long *block;
void *idx;
/* if (*n <= 0)
{
printf("N is negative or zero n");
exit(0);
} */
/* fprintf(stderr,"Bir = %i n",*n ); */
block=(long *)malloc((unsigned)*n);
/* if (block == (long *)NULL)
{
printf("Error in MALLOC - PANIC n");
exit(0);
} */
idx = block;
/* fprintf(stderr," ip = %i n",idx ); */
return(idx);
}
The SIGSEGV error comes when I try to assign a value to "kpt".
I changet the mallocw statements to the intrinsic function MALLOC, but I would then get an error in the memory.c when intCalloc is called.
I have a slightly different version of the code which I compile into a library and link to the commercial finite element software Abaqus, and I have been able to do that without any issues. The two codes only differ by a couple of files (i.e. main.F90 is absent from the library). Perhaps there are some linking flags that Abaqus uses that fixes the problem I am encountering when I try to compile and link on my own. I have tried numerous compiler and linker options including -cxxlib, as well as others.
One other thing. When I make the library version, I compile all the C code into a library (uvss_lib_lib.a). I then compile uvss_inv_lib.f and archive it with the C library into a new library (uvss_lib.a). Then when I compile the rest of the FORTRAN only objects (none of which is given here), I archive the mixed language library with it:
ar cr main_code.a *.o uvss_lib.a
When I try this procedure to build the executeable I link the mixed language library when I am compiling the executeable:
ifort -fPIC *.o -L./ uvss_lib.a -o main_code
However, when I do this it is unable to find any of the functions within the C library (uvss_lib_lib.a). Therefore, I am forced to compile and archive all the source within uvss_lib.a at once. The procedure I follow to compile the executeable successfully is as follows:
%Compile C code
>> icc -c -cxxlib -fPIC -fp-speculationsafe -traceback -debug -g *.c
%Compile uvss_inv_lib.f
>> ifort -c -fPIC -traceback -g -debug uvss_inv_lib.f
%Archive files
>>ar cr uvss_lib.a *.o *.h *.inc
%I then copy uvss_lib.a to another directory contain the rest of my already compile fortran objects and I compile the code
>> -ifort -fPIC -traceback -g -debug -cxxlib main.F90 *.o -L./ uvss_lib.a -lifport -lifcore -o main_code
I am not sure if this has anything to do with my error, but I am confused as to why if I try to link an .a archive that is composed of a .o object and a .a archive the compiler cannot find any of the functions with in the sub-archive.
Any help would be greatly appreciated, as I need to get this code working on Linux so I can finish my dissertation.
Thanks,
-Evan
I have a mostly Fortran code which I can compile successfully in Windows without any problems, however when I try to compile it on Linux I get a SIGSEGV error. The code contains a small portion written in C, and this is where the problems are caused. I did not write the code, and I have little experience with C, so I am having major issues fixing the error.
The section of the FORTRAN code (in uvss_in_lib.f) that is giving me problems is as follows:
subroutine uvss_lib(kneq,kncoeff,values,irow,icol,rhs,iflag)
include 'sord.inc'
dimension values(1),rhs(1)
dimension irow(1),icol(1)
INTEGER(KIND=INT_PTR_KIND()) :: i_kpt
pointer(i_kpt ,kpt(1))
INTEGER(KIND=INT_PTR_KIND()) :: i_maxa
pointer(i_maxa,maxa(1))
INTEGER(KIND=INT_PTR_KIND()) :: i_row2
pointer(i_row2,irow2(1))
INTEGER(KIND=INT_PTR_KIND()) :: i_values2
pointer(i_values2,values2(1))
if(iflag.eq.1) then
open(79,file='summary',status='scratch')
write(79,*) ' neq =',kneq
write(79,*) ' ncoeff =',kncoeff
endif
c if(iflag.eq.1) then
c write(79,*) '0- lic is fine ' ,kneq,kncoeff
c call send_file()
c endif
if(iflag.eq.1) then
i_maxa = mallocw((kneq+10)*nb,110)
i_kpt = mallocw((kneq+10)*nb,110)
i_values2 = mallocw((kncoeff+10)*nb,110)
i_row2 = mallocw((kncoeff+10)*nbi,110)
endif
call uvss_convert(kneq,kncoeff,values,irow,icol,rhs,maxa,
& irow2,values2,kpt,iflag)
if(iflag.eq.3) then
call free(i_maxa)
call free(i_kpt )
call free(i_values2 )
call free(i_row2 )
endif
return
end
subroutine uvss_convert(kneq,kncoeff,values,irow,icol,rhs,
& maxa,irow2,values2,kpt,iflag)
include 'sord.inc'
dimension values(1),rhs(1)
dimension irow(1),icol(1),maxa(1),kpt(1)
dimension values2(1),irow2(1)
do i = 1, kneq
kpt(i) = 0
enddo
...
...
...
return
end
where mallocw (mallocw.c) is C code:
#include
#include
#if defined (_CRAY) || defined (_WIN32)
# define mallocw MALLOCW
#else
#if !defined(_AIX) && !defined(__hpux)
# define mallocw mallocw_
#endif
#endif
void* mallocw(n,ii)
int *n;
int *ii;
{
long *block;
void *idx;
/* if (*n <= 0)
{
printf("N is negative or zero n");
exit(0);
} */
/* fprintf(stderr,"Bir = %i n",*n ); */
block=(long *)malloc((unsigned)*n);
/* if (block == (long *)NULL)
{
printf("Error in MALLOC - PANIC n");
exit(0);
} */
idx = block;
/* fprintf(stderr," ip = %i n",idx ); */
return(idx);
}
The SIGSEGV error comes when I try to assign a value to "kpt".
I changet the mallocw statements to the intrinsic function MALLOC, but I would then get an error in the memory.c when intCalloc is called.
I have a slightly different version of the code which I compile into a library and link to the commercial finite element software Abaqus, and I have been able to do that without any issues. The two codes only differ by a couple of files (i.e. main.F90 is absent from the library). Perhaps there are some linking flags that Abaqus uses that fixes the problem I am encountering when I try to compile and link on my own. I have tried numerous compiler and linker options including -cxxlib, as well as others.
One other thing. When I make the library version, I compile all the C code into a library (uvss_lib_lib.a). I then compile uvss_inv_lib.f and archive it with the C library into a new library (uvss_lib.a). Then when I compile the rest of the FORTRAN only objects (none of which is given here), I archive the mixed language library with it:
ar cr main_code.a *.o uvss_lib.a
When I try this procedure to build the executeable I link the mixed language library when I am compiling the executeable:
ifort -fPIC *.o -L./ uvss_lib.a -o main_code
However, when I do this it is unable to find any of the functions within the C library (uvss_lib_lib.a). Therefore, I am forced to compile and archive all the source within uvss_lib.a at once. The procedure I follow to compile the executeable successfully is as follows:
%Compile C code
>> icc -c -cxxlib -fPIC -fp-speculationsafe -traceback -debug -g *.c
%Compile uvss_inv_lib.f
>> ifort -c -fPIC -traceback -g -debug uvss_inv_lib.f
%Archive files
>>ar cr uvss_lib.a *.o *.h *.inc
%I then copy uvss_lib.a to another directory contain the rest of my already compile fortran objects and I compile the code
>> -ifort -fPIC -traceback -g -debug -cxxlib main.F90 *.o -L./ uvss_lib.a -lifport -lifcore -o main_code
I am not sure if this has anything to do with my error, but I am confused as to why if I try to link an .a archive that is composed of a .o object and a .a archive the compiler cannot find any of the functions with in the sub-archive.
Any help would be greatly appreciated, as I need to get this code working on Linux so I can finish my dissertation.
Thanks,
-Evan
連結已複製
2 回應
I don't have 'sord.inc' to test this.
BUT you may have a problem with pointer sizes. What are you expecting for the sizeof( void * ) ? You may investigate the -mcmodel=medium option on both Ifort and ICC to see if that helps.
But the bigger question: WHY mallocw and these old Cray pointers? 25 years ago before Fortran90 ALLOCATE, yes, probably would have used Cray pointers and calling C to do the allocation. But now, why? It may be time to recode this to modern standards and get rid of those Cray pointers and malloc() calls.
ron
BUT you may have a problem with pointer sizes. What are you expecting for the sizeof( void * ) ? You may investigate the -mcmodel=medium option on both Ifort and ICC to see if that helps.
But the bigger question: WHY mallocw and these old Cray pointers? 25 years ago before Fortran90 ALLOCATE, yes, probably would have used Cray pointers and calling C to do the allocation. But now, why? It may be time to recode this to modern standards and get rid of those Cray pointers and malloc() calls.
ron
Thanks Ron,
This is not my code, but rather a code that was given to me that I am making some modifications. It was definitely something with the pointers. I re-wrote the FORTRAN wrapper so that all the memory allocation was handled in FORTRAN, rather than C, and it works fine now.
This is not my code, but rather a code that was given to me that I am making some modifications. It was definitely something with the pointers. I re-wrote the FORTRAN wrapper so that all the memory allocation was handled in FORTRAN, rather than C, and it works fine now.