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-3422jacobs%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