|
Home > Archive > Unix Programming > April 2004 > Need help in tracking down an error
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Need help in tracking down an error
|
|
| Madhusudan Singh 2004-04-19, 12:33 am |
| Hi
I am trying to do some mixed F95/C programming in one of my
simulations. I have defined a C wrapper routine to use the system function
getenv() :
void fortrangetenv_(char *varnm, char *envnm, int *varnmlength,int
*envnmlength)
{
int status;
char *varname;
printf("%s,%s,%d,%d\n",varnm,envnm,*varnmlength,envnmlength);
if(!(varname=appendtostring(varnm,*varnm
length)))
{
perror("Failed : appendtostring (varname) in
posixwrapper:fortrangetenv");
exit(1);
}
if(!(envnm=getenv(varname)))
{
perror("Failed : getenv in posixwrapper:fortrangetenv");
exit(1);
}
}
The fortran call :
call fortrangetenv('DISPLAY',displaystring)
(The two extra length arguments are usually passed implicitly by Fortran
according to most online references I could find. appendtostring is another
C routine used to tack on a null character to a string :
char *appendtostring(char *str,int len)
{
char *res; /* C arrays are from 0:len-1 */
if((res=(char*)malloc(len+1)))
{
strncpy(res,str,len);
res[len]='\0';
}
return res;
}
).
I am using IFC (7.0) for F95 and gcc for C.
The program links correctly (and the symbol fortrangetenv_ exists in the C
object file - confirmed with nm) but quits with an Address Error
(indicating some kind of segmentation fault or something) :
** Address Error **
End of diagnostics
Interestingly, the printf statement in the C routine is not executed at all.
Where am I going wrong ?
Thanks,
MS
| |
| Madhusudan Singh 2004-04-19, 5:34 pm |
| On Monday 19 April 2004 03:54, Jugoslav Dujic (jdujic@yahoo.com) held forth
in comp.lang.fortran (<c600jl$5c74h$1@ID-106075.news.uni-berlin.de> ):
Thanks for your response.
> | (The two extra length arguments are usually passed implicitly by Fortran
> | according to most online references I could find.
>
> That's right, however, the MEANS of passing differ. I believe that
> the more common convention for these arguments is BY VALUE; thus,
> try it without pointer dereferencing. (And consult your manual).
Aha !
Changed the code to :
void fortrangetenv_(char *varnm, char *envnm, int varnmlength,int
envnmlength)
{
int status;
char *varname="getenv";
printf("varname = %s\n",varname);
if(!(varname=appendtostring(varnm,varnml
ength)))
{
perror("Failed : appendtostring (varname) in
posixwrapper:fortrangetenv");
exit(1);
}
if(!(envnm=getenv(varname)))
{
perror("Failed : getenv in posixwrapper:fortrangetenv");
exit(1);
}
printf("envnm = %s\n",envnm);
}
Now when I call this with :
call fortrangetenv('PATH',pathstring)
if(pathstring.eq.'') then
print*, ' Failed : path string not found'
status=-2
return
end if
lenpathstring=len_trim(pathstring)
print*,'pathstring =',trim(pathstring)
print*,'lenpathstring =',lenpathstring
I get :
envnm =
/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/usr/local/intel/compiler70/ia32/bin:/usr/local/maxima/bin:/usr/java/jdk1.3.1/bin:/usr/java/jre1.3.1/bin:/usr/local/intel/compiler70/ia32/bin:/usr/local/mozilla
pathstring = < 4096 blanks >
lenpathstring = 4096
** Address Error **
End of diagnostics
While I am somewhat confident that I can track down the address error from
now on, it bothers me that the string returned in pathstring is just a set
of blanks.
However, the value of envnm just before return from the C routine is a well
defined string (see o/p above). Why is this value not carrying over (the
string was passed by reference) ?
Possibly unrelated question : does Fortran chop off the null character at
the string (perhaps a dumb question to ask - but you never know the
idiosyncracies of compilers) or do I have to write a routine in fortran to
drop the last character ?
>
> | appendtostring is another
> | C routine used to tack on a null character to a string :
> | char *appendtostring(char *str,int len)
> | {
> | char *res; /* C arrays are from 0:len-1 */
> | if((res=(char*)malloc(len+1)))
> | {
> | strncpy(res,str,len);
> | res[len]='\0';
> | }
> | return res;
> | }
> |
> | Interestingly, the printf statement in the C routine is not executed at
> | all. Where am I going wrong ?
>
> Further, I see you foresaw the problem with \0 termination by supplying
> appendtostring routine, but you are using it AFTER printf, which means
> that printf doesn't get properly terminated strings.
>
That was a dumb mistake - fixed above.
|
|
|
|
|