Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d1139e0

Browse files
committed
PYMALLOC_DEBUG routines: The "check API family" gimmick was going nowhere
fast, and just cluttered the code. Get rid of it for now. If a compelling case can be made for it, easy to restore it later.
1 parent 7bf9715 commit d1139e0

2 files changed

Lines changed: 40 additions & 68 deletions

File tree

Include/pymem.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,14 @@ DL_IMPORT(void *) _PyMalloc_Realloc(void *p, size_t nbytes);
9797
DL_IMPORT(void) _PyMalloc_Free(void *p);
9898

9999
#ifdef PYMALLOC_DEBUG
100-
DL_IMPORT(void *) _PyMalloc_DebugMalloc(size_t nbytes, int family);
101-
DL_IMPORT(void *) _PyMalloc_DebugRealloc(void *p, size_t nbytes, int family);
102-
DL_IMPORT(void) _PyMalloc_DebugFree(void *p, int family);
100+
DL_IMPORT(void *) _PyMalloc_DebugMalloc(size_t nbytes);
101+
DL_IMPORT(void *) _PyMalloc_DebugRealloc(void *p, size_t nbytes);
102+
DL_IMPORT(void) _PyMalloc_DebugFree(void *p);
103103
DL_IMPORT(void) _PyMalloc_DebugDumpAddress(const void *p);
104104
DL_IMPORT(void) _PyMalloc_DebugCheckAddress(const void *p);
105-
#define _PyMalloc_MALLOC(N) _PyMalloc_DebugMalloc(N, 0)
106-
#define _PyMalloc_REALLOC(P, N) _PyMalloc_DebugRealloc(P, N, 0)
107-
#define _PyMalloc_FREE(P) _PyMalloc_DebugFree(P, 0)
105+
#define _PyMalloc_MALLOC _PyMalloc_DebugMalloc
106+
#define _PyMalloc_REALLOC _PyMalloc_DebugRealloc
107+
#define _PyMalloc_FREE _PyMalloc_DebugFree
108108

109109
#else /* WITH_PYMALLOC && ! PYMALLOC_DEBUG */
110110
#define _PyMalloc_MALLOC _PyMalloc_Malloc

Objects/obmalloc.c

Lines changed: 34 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -724,35 +724,13 @@ write4(void *p, ulong n)
724724
q[3] = (uchar)( n & 0xff);
725725
}
726726

727-
static void
728-
check_family(const void *p, int family)
729-
{
730-
const uchar *q = (const uchar *)p;
731-
int original_family;
732-
char buf[200];
733-
734-
assert(p != NULL);
735-
original_family = (int)*(q-4);
736-
if (family != original_family) {
737-
/* XXX better msg */
738-
PyOS_snprintf(buf, sizeof(buf),
739-
"free or realloc from family #%d called, "
740-
"but block was allocated by family #%d",
741-
family, original_family);
742-
_PyMalloc_DebugDumpAddress(p);
743-
Py_FatalError(buf);
744-
}
745-
}
746-
747727
/* The debug malloc asks for 16 extra bytes and fills them with useful stuff,
748728
here calling the underlying malloc's result p:
749729
750730
p[0:4]
751731
Number of bytes originally asked for. 4-byte unsigned integer,
752732
big-endian (easier to read in a memory dump).
753-
p[4]
754-
The API "family" this malloc call belongs to. XXX todo XXX
755-
p[5:8]
733+
p[4:8]
756734
Copies of PYMALLOC_FORBIDDENBYTE. Used to catch under- writes
757735
and reads.
758736
p[8:8+n]
@@ -773,14 +751,12 @@ p[8+n+4:8+n+8]
773751
*/
774752

775753
void *
776-
_PyMalloc_DebugMalloc(size_t nbytes, int family)
754+
_PyMalloc_DebugMalloc(size_t nbytes)
777755
{
778756
uchar *p; /* base address of malloc'ed block */
779757
uchar *tail; /* p + 8 + nbytes == pointer to tail pad bytes */
780758
size_t total; /* nbytes + 16 */
781759

782-
assert(family == 0);
783-
784760
bumpserialno();
785761
total = nbytes + 16;
786762
if (total < nbytes || (total >> 31) > 1) {
@@ -792,13 +768,12 @@ _PyMalloc_DebugMalloc(size_t nbytes, int family)
792768
return NULL;
793769
}
794770

795-
p = _PyMalloc_Malloc(total); /* XXX derive from family */
771+
p = _PyMalloc_Malloc(total);
796772
if (p == NULL)
797773
return NULL;
798774

799775
write4(p, nbytes);
800-
p[4] = (uchar)family;
801-
p[5] = p[6] = p[7] = PYMALLOC_FORBIDDENBYTE;
776+
p[4] = p[5] = p[6] = p[7] = PYMALLOC_FORBIDDENBYTE;
802777

803778
if (nbytes > 0)
804779
memset(p+8, PYMALLOC_CLEANBYTE, nbytes);
@@ -816,38 +791,31 @@ _PyMalloc_DebugMalloc(size_t nbytes, int family)
816791
Then calls the underlying free.
817792
*/
818793
void
819-
_PyMalloc_DebugFree(void *p, int family)
794+
_PyMalloc_DebugFree(void *p)
820795
{
821796
uchar *q = (uchar *)p;
822797
size_t nbytes;
823798

824-
assert(family == 0);
825-
826799
if (p == NULL)
827800
return;
828-
check_family(p, family);
829801
_PyMalloc_DebugCheckAddress(p);
830802
nbytes = read4(q-8);
831803
if (nbytes > 0)
832804
memset(q, PYMALLOC_DEADBYTE, nbytes);
833-
_PyMalloc_Free(q-8); /* XXX derive from family */
805+
_PyMalloc_Free(q-8);
834806
}
835807

836808
void *
837-
_PyMalloc_DebugRealloc(void *p, size_t nbytes, int family)
809+
_PyMalloc_DebugRealloc(void *p, size_t nbytes)
838810
{
839811
uchar *q = (uchar *)p;
840812
size_t original_nbytes;
841813
void *fresh; /* new memory block, if needed */
842814

843-
assert(family == 0);
844-
845815
if (p == NULL)
846-
return _PyMalloc_DebugMalloc(nbytes, family);
816+
return _PyMalloc_DebugMalloc(nbytes);
847817

848-
check_family(p, family);
849818
_PyMalloc_DebugCheckAddress(p);
850-
851819
original_nbytes = read4(q-8);
852820
if (nbytes == original_nbytes) {
853821
/* note that this case is likely to be common due to the
@@ -864,52 +832,57 @@ _PyMalloc_DebugRealloc(void *p, size_t nbytes, int family)
864832
bumpserialno();
865833
write4(q-8, nbytes);
866834
/* kill the excess bytes plus the trailing 8 pad bytes */
867-
memset(q + nbytes, PYMALLOC_DEADBYTE, excess + 8);
868835
q += nbytes;
869836
q[0] = q[1] = q[2] = q[3] = PYMALLOC_FORBIDDENBYTE;
870837
write4(q+4, serialno);
838+
memset(q+8, PYMALLOC_DEADBYTE, excess);
871839
return p;
872840
}
873841

874842
/* More memory is needed: get it, copy over the first original_nbytes
875843
of the original data, and free the original memory. */
876-
fresh = _PyMalloc_DebugMalloc(nbytes, family);
844+
fresh = _PyMalloc_DebugMalloc(nbytes);
877845
if (fresh != NULL && original_nbytes > 0)
878846
memcpy(fresh, p, original_nbytes);
879-
_PyMalloc_DebugFree(p, family);
847+
_PyMalloc_DebugFree(p);
880848
return fresh;
881849
}
882850

883851
void
884852
_PyMalloc_DebugCheckAddress(const void *p)
885853
{
886854
const uchar *q = (const uchar *)p;
887-
char *msg = NULL;
855+
char *msg;
856+
int i;
888857

889-
if (p == NULL)
858+
if (p == NULL) {
890859
msg = "didn't expect a NULL pointer";
860+
goto error;
861+
}
891862

892-
else if (*(q-3) != PYMALLOC_FORBIDDENBYTE ||
893-
*(q-2) != PYMALLOC_FORBIDDENBYTE ||
894-
*(q-1) != PYMALLOC_FORBIDDENBYTE)
895-
msg = "bad leading pad byte";
863+
for (i = 4; i >= 1; --i) {
864+
if (*(q-i) != PYMALLOC_FORBIDDENBYTE) {
865+
msg = "bad leading pad byte";
866+
goto error;
867+
}
868+
}
896869

897-
else {
870+
{
898871
const ulong nbytes = read4(q-8);
899872
const uchar *tail = q + nbytes;
900-
int i;
901873
for (i = 0; i < 4; ++i) {
902874
if (tail[i] != PYMALLOC_FORBIDDENBYTE) {
903875
msg = "bad trailing pad byte";
904-
break;
876+
goto error;
905877
}
906878
}
907879
}
908880

909-
if (msg != NULL) {
910-
_PyMalloc_DebugDumpAddress(p);
911-
Py_FatalError(msg);
912-
}
881+
return;
882+
883+
error:
884+
_PyMalloc_DebugDumpAddress(p);
885+
Py_FatalError(msg);
913886
}
914887

915888
void
@@ -918,29 +891,29 @@ _PyMalloc_DebugDumpAddress(const void *p)
918891
const uchar *q = (const uchar *)p;
919892
const uchar *tail;
920893
ulong nbytes, serial;
894+
int i;
921895

922896
fprintf(stderr, "Debug memory block at address p=%p:\n", p);
923897
if (p == NULL)
924898
return;
925899

926900
nbytes = read4(q-8);
927901
fprintf(stderr, " %lu bytes originally allocated\n", nbytes);
928-
fprintf(stderr, " from API family #%d\n", *(q-4));
929902

930903
/* In case this is nuts, check the pad bytes before trying to read up
931904
the serial number (the address deref could blow up). */
932905

933-
fputs(" the 3 pad bytes at p-3 are ", stderr);
934-
if (*(q-3) == PYMALLOC_FORBIDDENBYTE &&
906+
fputs(" the 4 pad bytes at p-4 are ", stderr);
907+
if (*(q-4) == PYMALLOC_FORBIDDENBYTE &&
908+
*(q-3) == PYMALLOC_FORBIDDENBYTE &&
935909
*(q-2) == PYMALLOC_FORBIDDENBYTE &&
936910
*(q-1) == PYMALLOC_FORBIDDENBYTE) {
937911
fputs("PYMALLOC_FORBIDDENBYTE, as expected\n", stderr);
938912
}
939913
else {
940-
int i;
941914
fprintf(stderr, "not all PYMALLOC_FORBIDDENBYTE (0x%02x):\n",
942915
PYMALLOC_FORBIDDENBYTE);
943-
for (i = 3; i >= 1; --i) {
916+
for (i = 4; i >= 1; --i) {
944917
const uchar byte = *(q-i);
945918
fprintf(stderr, " at p-%d: 0x%02x", i, byte);
946919
if (byte != PYMALLOC_FORBIDDENBYTE)
@@ -958,7 +931,6 @@ _PyMalloc_DebugDumpAddress(const void *p)
958931
fputs("PYMALLOC_FORBIDDENBYTE, as expected\n", stderr);
959932
}
960933
else {
961-
int i;
962934
fprintf(stderr, "not all PYMALLOC_FORBIDDENBYTE (0x%02x):\n",
963935
PYMALLOC_FORBIDDENBYTE);
964936
for (i = 0; i < 4; ++i) {

0 commit comments

Comments
 (0)