Tim Peters <tim.one@comcast.net> writes: > The thing I've dreaded most about switching to pymalloc is losing the > invaluable memory-corruption clues supplied by the Microsoft debug-build > malloc. On more than one occasion, they've found wild stores, out-of-bounds > reads, reads of uninitialized memory, and reads of free()ed memory in > Python. It does this by spraying special bytes all over malloc'ed memory at > various times, then checking the bytes for sanity at free() and realloc() > times. [...] > Sketch of Debug Mode for PyMalloc > > + Three new entry points in obmalloc.c (note: stop #include'ing this; > hiding code in include files sucks, and naming an include file .c > compounds the confusion): +1 > DL_IMPORT(void *) _PyMalloc_DebugMalloc(size_t nbytes); > DL_IMPORT(void *) _PyMalloc_DebugRealloc(void *p, size_t nbytes); > DL_IMPORT(void) _PyMalloc_DebugFree(void *p); > > + When WITH_PYMALLOC and PYMALLOC_DEBUG are #define'd, these are > mapped to in the obvious way from _PyMalloc_{MALLOC, REALLOC, FREE}: > > #ifdef WITH_PYMALLOC > DL_IMPORT(void *) _PyMalloc_Malloc(size_t nbytes); > DL_IMPORT(void *) _PyMalloc_Realloc(void *p, size_t nbytes); > DL_IMPORT(void) _PyMalloc_Free(void *p); > > DL_IMPORT(void *) _PyMalloc_DebugMalloc(size_t nbytes); > DL_IMPORT(void *) _PyMalloc_DebugRealloc(void *p, size_t nbytes); > DL_IMPORT(void) _PyMalloc_DebugFree(void *p); > > #ifdef PYMALLOC_DEBUG > #define _PyMalloc_MALLOC _PyMalloc_DebugMalloc > #define _PyMalloc_REALLOC _PyMalloc_DebugRealloc > #define _PyMalloc_FREE _PyMalloc_DebugFree > > #else /* WITH_PYMALLOC && !PYMALLOC_DEBUG */ > #define _PyMalloc_MALLOC _PyMalloc_Malloc > #define _PyMalloc_REALLOC _PyMalloc_Realloc > #define _PyMalloc_FREE _PyMalloc_Free > > #endif /* PYMALLOC_DEBUG */ > > #else /* !WITH_PYMALLOC */ > #define _PyMalloc_MALLOC PyMem_MALLOC > #define _PyMalloc_REALLOC PyMem_REALLOC > #define _PyMalloc_FREE PyMem_FREE > #endif /* WITH_PYMALLOC */ Presuambly it would be possible to do this wrapped around malloc() & free() too? No real point, I guess. > + A debug build implies PYMALLOC_DEBUG, but PYMALLOC_DEBUG can > be forced in a release build. > > + No changes to the guts of _PyMalloc_{Malloc, Realloc, Free}. Keep > them as lean and as clear of #ifdef obscurity as they are now. +1 > + Define three special bit patterns. In hex, they all end with B > (for deBug <wink>), and begin with a vaguely mnemonic letter. > Strings of these are unlikely to be legit memory addresses, ints, > 7-bit ASCII, or floats: [snip good stuff] > + The Debug free first uses the address to find the number of bytes > originally asked for, then checks the 8 bytes on each end for > sanity (in particular, that the PYMALLOC_FORBIDDENBYTEs are still > intact). > XXX Make this checking a distinct entry point. Yes. Particularly if you can call it from gdb. > XXX In case an error is found, print informative stuff, but then what? > XXX Die or keep going? Fatal error is probably best. > Then fills the original N bytes with PYMALLOC_DEADBYTE. This is to > catch references to free()ed memory. The forbidden bytes are left > intact. > Then calls _PyMalloc_Free. Is it worth having an option where you *don't* call _Free? Obviously, this would chew memory like no tomorrow, but it might just catch more errors. > + The Debug realloc first calls _PyMalloc_DebugMalloc with the new > request size. > Then copies over the original bytes. > The calls _PyMalloc_DebugFree on the original bytes. > XXX This could, and probably should, be optimized to avoid copying > XXX every time. Yes. What are you waiting for? <wink> Cheers, M. -- If comp.lang.lisp *is* what vendors are relying on to make or break Lisp sales, that's more likely the problem than is the effect of any one of us on such a flimsy marketing strategy... -- Kent M Pitman, comp.lang.lisp
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4