[comp.sys.ibm.pc] How Turbo C Handles Null Pointer Assignments

forrest@sybase.com (05/10/89)

I've just figured out some interesting facts about how Turbo C 2.0
detects null pointer assignments. Since this doesn't appear to be
documented I thought I'd pass along what I've learned.

All this started when I saw the message "Null Pointer Assignment"
when running a program. This was surprising to me at first because
I didn't know how a computer could detect null pointer assignments
without using some kind of hardware memory protection scheme.
After looking at the c0m.asm source code supplied with Turbo C I
figured out what was going happening. Turbo C stores a check sum
of the memory area starting with address 0 and continuing through
where the message is stored that you see when you run Turbo C.
As part of the _exit() procedure, this checksum is recomputed and
compared to the original checksum.
If you accidently put something in address 0 using a null pointer
assignment these two values won't be the same a Turbo C prints
the "Null Pointer Assignment" message.

Although I haven't tried this yet, I think it would be possible to
detect null pointer assignments at run time by setting a watchpoint
on address 0 (I use the Turbo Debugger. I don't know if you can do this
with the debugger that comes with Turbo C). Then, whenever the value
at address 0 changes you will be notified.

Jon Forrest
forrest@sybase.com
{pacbell,sun,{uunet,ucbvax}!mtxinu}!sybase!forrest
415-596-3422

jacobs%cmos.utah.edu@wasatch.utah.edu (Steven R. Jacobs) (05/11/89)

In article <4178@sybase.sybase.com> forrest@sybase.com writes:
>After looking at the c0m.asm source code supplied with Turbo C I
>figured out what was going happening. Turbo C stores a check sum
>of the memory area starting with address 0 and continuing through
>where the message is stored that you see when you run Turbo C.

This "checksum" is actually the Turbo C copyright string.  If it
gets tromped on, the "Null Pointer Assignment" message is given.
You can verify this by looking at location 0 with the debugger,
assuming you look there before your program tromps on the data.

Steve Jacobs  ({ihnp4,decvax}!utah-cs!jacobs, jacobs@cs.utah.edu)

dmt@mtunb.ATT.COM (Dave Tutelman) (05/11/89)

In article <1778@wasatch.utah.edu> jacobs%cmos.utah.edu@wasatch.utah.edu (Steven R. Jacobs) writes:
>In article <4178@sybase.sybase.com> forrest@sybase.com writes:
>>... [ Turbo C checks ] ...
>>the memory area starting with address 0 and continuing through
>>where the message is stored that you see when you run Turbo C.
>
>This "checksum" is actually the Turbo C copyright string.  If it
>gets tromped on, the "Null Pointer Assignment" message is given.

Both Microsoft C and Turbo C detect Null Pointer Assignments this way.
(Maybe others do as well.)  The code below is a debugging tool I have
occasionally used to track down null pointer assignments in C programs.
It is based on the same principle.
It has worked in Microsoft C 4.x and 5.0, and Turbo C 1.0 and 2.0.
It remains independent of which compiler/version you use because it
initializes its reference string at run time (based on the initial
contents of the null-pointer area).

Enjoy!
+---------------------------------------------------------------+
|    Dave Tutelman						|
|    Physical - AT&T Bell Labs  -  Middletown, NJ		|
|    Logical -  ...att!mtunb!dmt				|
|    Audible -  (201) 957 6583					|
+---------------------------------------------------------------+

/*************************************************************
 *
 *	NULLPTR - Dave Tutelman - March 1988
 *
 *	Test for a null pointer violation.
 *	Complain and quit if found.
 *
 *	nullptr (string)
 *		char *string;
 *
 *	FIRST CALL - string should be empty (""), to initialize.
 *	SUBSEQUENT CALLS - if a null pointer violation is found,
 *		the program displays (1) the string, and (2) the
 *		null pointer area violations,  then quits.
 *
 *	As distributed, this file contains a sample main program to
 *	   (1) demonstrate the use of nullptr(), and
 *	   (2) test its effectiveness in your environment.
 *	To use nullpr() in your own program, recompile after commenting out
 *	the "#define SAMPLE" line.
 */

#define SAMPLE

#include <stdio.h>

#define	NULLVECSIZE	80

static char nullvector[NULLVECSIZE];

nullptr (s)
	char *s;
{
	int	i;
	char	*p;

	if (!strlen (s)) {	/* initialize nullvector */
		for (i=0, p=NULL; i<NULLVECSIZE; i++,p++)
			nullvector [i] = *p;
	}

	else {		/* check to see if null vector has changed */
		for (i=0, p=NULL; i<NULLVECSIZE; i++,p++)
			if (nullvector [i] != *p)  quit (s);
	}
}


quit (s)
	char *s;
{
	int	i;
	char	*p;

	printf ("\nNULL POINTER VIOLATION DETECTED!\n");
	printf ("%s\n", s);

	printf ("\nOriginal and corrupted values of vector\n");
	printf (" n    Hex    Char\n");
	for (i=0, p=NULL; i<NULLVECSIZE; i++,p++)
		if (nullvector[i] != *p)
			printf ("%2d   %2X %2X   %c %c\n", i,
				nullvector[i], *p, nullvector[i], *p);

	exit (-1);
}


#ifdef SAMPLE
/******************************************************************
 *
 *	Sample main program for nullptr ()
 */

main ()
{
	char	*p;

	nullptr ("");		/* initialize */

	nullptr ("Nothing yet!");

	p = NULL;  p +=4;
	*p = 'V';	/* violate the null ptr area */
	p += 20;
	*p = 'I';	/* and again */
	nullptr ("This one should catch it!");

	printf ("Shouldn't ever get here - printf\n");
	nullptr ("Shouldn't ever get here - nullprt\n");
}

#endif