Unix Programming - Need help in tracking down an error

This is Interesting: Free IT Magazines  
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.
Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com