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