summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2002-07-10 19:29:49 (GMT)
committerTim Peters <tim.peters@gmail.com>2002-07-10 19:29:49 (GMT)
commit889f61dcfbdccf4d1de7da354ee6165e488e4665 (patch)
treea0a78b00f5372fb4b43a7f87a2ea9325fbaa6a94
parente4523c46b9430a29d00995a50b723536cebbd18c (diff)
downloadcpython-889f61dcfbdccf4d1de7da354ee6165e488e4665.zip
cpython-889f61dcfbdccf4d1de7da354ee6165e488e4665.tar.gz
cpython-889f61dcfbdccf4d1de7da354ee6165e488e4665.tar.bz2
Documented PYMALLOC_DEBUG. This completes primary coverage of all the
"special builds" I ever use. If you use others, document them here, or don't be surprised if I rip out the code for them <0.5 wink>.
-rw-r--r--Misc/SpecialBuilds.txt52
-rw-r--r--Objects/obmalloc.c2
2 files changed, 53 insertions, 1 deletions
diff --git a/Misc/SpecialBuilds.txt b/Misc/SpecialBuilds.txt
index 0551c8e..0851aa5 100644
--- a/Misc/SpecialBuilds.txt
+++ b/Misc/SpecialBuilds.txt
@@ -60,6 +60,58 @@ envar PYTHONDUMPREFS
---------------------------------------------------------------------------
PYMALLOC_DEBUG
+When pymalloc is enabled (WITH_PYMALLOC is defined), calls to the PyObject_
+memory routines are handled by Python's own small-object allocator, while
+calls to the PyMem_ memory routines are directed to the system malloc/
+realloc/free. If PYMALLOC_DEBUG is also defined, calls to both PyObject_
+and PyMem_ memory routines are directed to a special debugging mode of
+Python's small-object allocator.
+
+This mode fills dynamically allocated memory blocks with special,
+recognizable bit patterns, and adds debugging info on each end of
+dynamically allocated memory blocks. The special bit patterns are:
+
+#define CLEANBYTE 0xCB /* clean (newly allocated) memory */
+#define DEADBYTE 0xDB /* dead (newly freed) memory */
+#define FORBIDDENBYTE 0xFB /* fordidden -- untouchable bytes */
+
+Strings of these bytes are unlikely to be valid addresses, floats, or 7-bit
+ASCII strings.
+
+8 bytes are added at each end of each block of N bytes requested. The
+memory layout is like so, where p represents the address returned by a
+malloc-like or realloc-like function:
+
+p[-8:-4]
+ Number of bytes originally asked for. 4-byte unsigned integer,
+ big-endian (easier to read in a memory dump).
+p[-4:0]
+ Copies of FORBIDDENBYTE. Used to catch under- writes and reads.
+p[0:N]
+ The requested memory, filled with copies of CLEANBYTE.
+ Used to catch reference to uninitialized memory.
+ When a realloc-like function is called requesting a larger memory
+ block, the new excess bytes are also filled with CLEANBYTE.
+ When a free-like function is called, these are overwritten with
+ DEADBYTE, to catch reference to free()ed memory. When a realloc-
+ like function is called requesting a smaller memory block, the excess
+ old bytes are also filled with DEADBYTE.
+p[N:N+4]
+ Copies of FORBIDDENBYTE. Used to catch over- writes and reads.
+p[N+4:N+8]
+ A serial number, incremented by 1 on each call to a malloc-like or
+ realloc-like function.
+ 4-byte unsigned integer, big-endian.
+ If "bad memory" is detected later, the serial number gives an
+ excellent way to set a breakpoint on the next run, to capture the
+ instant at which this block was passed out.
+
+A malloc-like or free-like function first checks that the FORBIDDENBYTEs
+at each end are intact. If they've been altered, diagnostic output is
+written to stderr, and the program is aborted by Py_FatalError().
+
+Note that PYMALLOC_DEBUG requires WITH_PYMALLOC.
+
Special gimmicks:
envar PYTHONMALLOCSTATS
diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c
index 14f9e25..22481ad 100644
--- a/Objects/obmalloc.c
+++ b/Objects/obmalloc.c
@@ -881,7 +881,7 @@ PyObject_Free(void *p)
#undef DEADBYTE
#undef FORBIDDENBYTE
#define CLEANBYTE 0xCB /* clean (newly allocated) memory */
-#define DEADBYTE 0xDB /* deed (newly freed) memory */
+#define DEADBYTE 0xDB /* dead (newly freed) memory */
#define FORBIDDENBYTE 0xFB /* untouchable bytes at each end of a block */
static ulong serialno = 0; /* incremented on each debug {m,re}alloc */