The mysterious error message

Chris Torek chris at mimsy.UUCP
Wed Nov 26 07:18:24 AEST 1986


In article <1376 at umd5> cgs at 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 at mimsy.umd.edu



More information about the Comp.unix.questions mailing list