[comp.unix.questions] The mysterious error message

cgs@umd5 (Chris Sylvain) (11/25/86)

[]
If anyone's mail gets bounced back, it's because the account-name here
has changed (see below).

The consensus of opinion is the environment is getting trashed. I'm going
to have to see what I can do with "dbx". It's strange that the environment
is getting trashed when I don't pass **envp to the program, and I never
attempt to do anything to the environment via a system() call.
Since I've received a note that I'm not the only one to have noticed this,
I'm including the following response I received for everyone's benefit:

> From: trwrb!ljp@ucbvax.Berkeley.EDU (Laura J. Pearlman)
> Organization: TRW EDS, Redondo Beach, CA
>
> Perhaps something in your .cshrc or .login file is doing something
> unexpected to your environment.  Why don't you try typing "/bin/sh"
> from the terminal, to see whether you get the same error, or typing
> "printenv" from the terminal to see whether you get something
> unusual?
>
As I stated in my original posting, everything works fine and as
expected when I type the command line in system() to either csh or sh.

>
> If that doesn't turn out to be it, you might be accidentally
> overwriting envp in your program somewhere -- you could try
> printing out your environment in your program at the point
> where you normally call system(3)...
>
>		-- Laura Pearlman
>		...{ucbvax,hplabs!decvax}!trwrb!ljp

Don't think I could overwrite **envp (see above). Also the code I'm
using generates no complaints from lint (the first thing I did when
I started having problems). Also, the code had previously worked fine
under 2.9BSD and Ultrix V1.2 ...
I've tried to do system("printenv"), but that too generates the error.
So, I'm left with poking around with "dbx" until I find out what is
going on.
Thanks to everyone who responded so far.

-- 
--==---==---==--
.. And hast thou slain the Jabberwock? ..

ARPA: cgs@umd5.UMD.EDU     BITNET: cgs%umd5@umd2
UUCP: ..!seismo!umd5.umd.edu!cgs

chris@mimsy.UUCP (Chris Torek) (11/26/86)

In article <1376@umd5> cgs@umd5 (Chris Sylvain) writes:
>The consensus of opinion is the environment is getting trashed.

Correct.

>I'm going to have to see what I can do with "dbx".

Quite a bit, if you have a working version.  The 4.2 dbx was largely
broken.  I never tried the updated version posted from Stanford by Mark
Linton.  The 4.3 version seems to work.  Using dbx is slow but sure;
just tell dbx to stop when the appropriate memory location is over-
written, then wait, and wait....  But first you must find this location:

>It's strange that the environment is getting trashed when I don't
>pass **envp to the program, and I never attempt to do anything to
>the environment via a system() call.

`system()' does not alter the environment.  The most common causes
for this are stray pointers and buffer overruns.  E.g.,

	main(argc, argv)
		int argc;
		char **argv;
	{

		argv[argc + 1] = "00";
		system("echo it worked");
		exit(0);
	}

produces `00: not an identifier', since the environment pointers
are stored in the process's stack just above the argv pointers.
The truth of the previous statement is system dependent, which
could explain why the code worked on other machines and other
releases.

>I've tried to do system("printenv"), but that too generates the error.

Naturally, for the error is coming from /bin/sh, and system() works
by passing its argument string as a command to /bin/sh.  This will
work . . .

	printenv()
	{
		int pid, w, status;

		switch (pid = fork()) {

		case -1:		/* out of resources */
			perror("fork");
			return;

		case 0:			/* child */
			execl("/usr/ucb/printenv", "printenv", (char *) 0);
			perror("exec(/usr/ucb/printenv)");
			_exit(1);
		}
		/* parent */
		while ((w = wait(&status)) != pid && w != -1)
			/*void*/;
		if (w == -1)
			printf("child vanished?\n");
		else if (status != 0)
			printf("printenv failed, status=%d\n", status);
		return;
	}

. . . *if* your printenv is in /usr/ucb.  (Using execlp() in an
environment-debugging routine is a bad idea, for execlp() itself
reads the environment to find $PATH.)  This is, however, overkill,
as the code for /usr/ucb/printenv itself is trivial:

	printenv()
	{
		extern char **environ;
		register char **p = environ;

		while (*p != NULL)
			printf("%s\n", *p++);
	}

(`Printenv' is actually a bit more complex, since it will optionally
print only a single environment string.)  Note that if the environment
pointers themselves are gongled*, this routine will crash with a
segmentation fault or bus error---which may perhaps be considered
a good thing....

--------
*This word comes by way of Avram Davidson and Grania Davis, in the
recent short story, `Addrict'.  I think it has a wonderful flavour.
(And *that* was a triple pun.)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
UUCP:	seismo!mimsy!chris	ARPA/CSNet:	chris@mimsy.umd.edu

levy@ttrdc.UUCP (Daniel R. Levy) (11/27/86)

In article <1376@umd5>, cgs@umd5.UUCP writes:
>The consensus of opinion is the environment is getting trashed. I'm going
>to have to see what I can do with "dbx". It's strange that the environment
>is getting trashed when I don't pass **envp to the program, and I never
>attempt to do anything to the environment via a system() call.
>Since I've received a note that I'm not the only one to have noticed this,
>I'm including the following response I received for everyone's benefit:
>
>I've tried to do system("printenv"), but that too generates the error.
>So, I'm left with poking around with "dbx" until I find out what is
>going on.
>.. And hast thou slain the Jabberwock? ..

	You could try something like replacing system() with code which
	actually prints out the environment, since printenv may filter
	out garbage even if invoked directly via execlp() (I don't have
	BSD src handy here, but SysV env filters out environment garbage).
	E.g.:

extern char **environ;
#define system(stuff) \
	{ \
	    int ep=0; \
	    while(environ[ep]) \
		(void) printf("%s\n",environ[ep++]); \
	}

Question: does the code do any writing into its argument vector?  Or question-
able indexing upon automatic arrays?  On SysV on a 3B20, the following will
evoke your "00: not an identifier" diagnostic:

main(argc,argv)
char **argv;
{
	argv[argc+1]="00";	/* messing with invalid argument */
	(void) system("echo hello, world");
}

So will this, after a few iterations (eventually core dumping):

main()
{
	auto char *c[1];
	register int i=0;
	while (1) {
		c[--i]="00";	/* messing with stack */
		(void) system("echo hello, world");
	}
}

"hope this helps"
-- 
 -------------------------------    Disclaimer:  The views contained herein are
|       dan levy | yvel nad      |  my own and are not at all those of my em-
|         an engihacker @        |  ployer or the administrator of any computer
| at&t computer systems division |  upon which I may hack.
|        skokie, illinois        |
 --------------------------------   Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa,
	   go for it!  			allegra,ulysses,vax135}!ttrdc!levy