[comp.unix.xenix] strings

myxm@beta.UUCP (Mike Mitchell) (10/07/87)

I have been working on porting down some of my more favorite utilities
from a BSD4.3 machine to uport sysv and I have been hitting some really
nasty problems. I was wondering if someone might have a nifty solution.

Basically the problem occurs with some of the routines which manipulate
(char *) pointers.  There is a call to strdup in one of my utilities which
I wound up writing with the following code:

char *strdup(str)
char *str;
{
	return(strcpy((char *)malloc(strlen(str)+1),str));
}

This routine functions anywhere between 0 and 5 times before it bombs.
I have been compiling with the large memory model and using the "debug
printfs" to watch it work.

In using sdb to find out what died from the core dump, the stack shows
that strcpy was the routine which gave up the ghost. I figured that I
could write a strcpy which looks like:

char *strcpy(str1, str2)
char *str1, *str2;
{
	char *sp;

	for (sp = str1; *str2 != 0; sp++, str2++)
		*sp = *str2;
	*sp = 0;
	return(str1);
}

Now this works fine for a few calls, but then it pukes up and dies!
This thing is not doing anything real fancy so is there some trick
with the segmented large model that I am missing out on? There are
no bizzarre pointer manipulations in this piece of code...

Thanks for any information which may help me out of this situation.

Mike Mitchell
myxm@lanl.gov
...!cmcl2!lanl!myxm

steve@nuchat.UUCP (Steve Nuchia) (10/16/87)

In article <10979@beta.UUCP>, myxm@beta.UUCP (Mike Mitchell) writes:
> I have been working on porting down some of my more favorite utilities
> from a BSD4.3 machine to uport sysv and I have been hitting some really
> nasty problems. I was wondering if someone might have a nifty solution.
> 
> Basically the problem occurs with some of the routines which manipulate
> (char *) pointers.  There is a call to strdup in one of my utilities which
> I wound up writing with the following code:
> 
> char *strdup(str)
> char *str;
> {
> 	return(strcpy((char *)malloc(strlen(str)+1),str));
> }

Did you declare malloc?  I thought not.  Bet it works in small model.

> This routine functions anywhere between 0 and 5 times before it bombs.
> I have been compiling with the large memory model and using the "debug
> printfs" to watch it work.

That many?  Pretty good...

> In using sdb to find out what died from the core dump, the stack shows
> that strcpy was the routine which gave up the ghost. I figured that I
> could write a strcpy which looks like:
> 
> char *strcpy(str1, str2)
[correct (if verbose) program text deleted]
> 
> Now this works fine for a few calls, but then it pukes up and dies!
> This thing is not doing anything real fancy so is there some trick
> with the segmented large model that I am missing out on? There are
> no bizzarre pointer manipulations in this piece of code...

Big suprise - you pass it a bogus destination pointer and it dies.
What did you expect?

Look people, run lint before posting pleas for help to the net.
Lint would have found this one.

For anyone who hasn't heard this before, a description of why
this breaks follows.  Hit n now.

In C, an undeclared function defaults to type "int".  Under uPort
and most other 286 OSs ints are 16 bits.  In large model pointers
are 32 bits.  The compiler sees the result of an integer function call,
malloc, cast to a pointer and passed to another function.  It dutifully
sign-extends the low-order (probably) part of malloc's return value
and sticks it on the stack, where it does a rather poor job of
imitating a pointer.  Whoever gets stuck with using that pointer,
strcpy in this case, chokes and dies.  Without the cast it would
be passed as an int, throwing off the other arguments and bringing
stack trash into the equation.

Use Lint.  It Pays.
-- 
Steve Nuchia	    | [...] but the machine would probably be allowed no mercy.
uunet!nuchat!steve  | In other words then, if a machine is expected to be
(713) 334 6720	    | infallible, it cannot be intelligent.  - Alan Turing, 1947