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