@@ -1418,7 +1418,7 @@ static void *
1418
1418
_PyMem_DebugRawAlloc (int use_calloc , void * ctx , size_t nbytes )
1419
1419
{
1420
1420
debug_alloc_api_t * api = (debug_alloc_api_t * )ctx ;
1421
- uint8_t * p ; /* base address of malloc'epad d block */
1421
+ uint8_t * p ; /* base address of malloc'ed pad block */
1422
1422
uint8_t * data ; /* p + 2*SST == pointer to data bytes */
1423
1423
uint8_t * tail ; /* data + nbytes == pointer to tail pad bytes */
1424
1424
size_t total ; /* 2 * SST + nbytes + 2 * SST */
@@ -1516,45 +1516,83 @@ _PyMem_DebugRawRealloc(void *ctx, void *p, size_t nbytes)
1516
1516
}
1517
1517
1518
1518
debug_alloc_api_t * api = (debug_alloc_api_t * )ctx ;
1519
- uint8_t * q ; /* base address of malloc'epad d block */
1520
- uint8_t * data ; /* p + 2*SST == pointer to data bytes */
1519
+ uint8_t * head ; /* base address of malloc'ed pad block */
1520
+ uint8_t * data ; /* pointer to data bytes */
1521
+ uint8_t * r ;
1521
1522
uint8_t * tail ; /* data + nbytes == pointer to tail pad bytes */
1522
1523
size_t total ; /* 2 * SST + nbytes + 2 * SST */
1523
1524
size_t original_nbytes ;
1524
- int i ;
1525
+ size_t se
10000
rialno ;
1526
+ #define ERASED_SIZE 64
1527
+ uint8_t save [2 * ERASED_SIZE ]; /* A copy of erased bytes. */
1525
1528
1526
1529
_PyMem_DebugCheckAddress (api -> api_id , p );
1527
1530
1528
- q = (uint8_t * )p ;
1529
- original_nbytes = read_size_t (q - 2 * SST );
1531
+ data = (uint8_t * )p ;
1532
+ head = data - 2 * SST ;
1533
+ original_nbytes = read_size_t (head );
1530
1534
if (nbytes > (size_t )PY_SSIZE_T_MAX - 4 * SST ) {
1531
1535
/* integer overflow: can't represent total as a Py_ssize_t */
1532
1536
return NULL ;
1533
1537
}
1534
1538
total = nbytes + 4 * SST ;
1535
1539
1536
- /* Resize and add decorations. */
1537
- q = (uint8_t * )api -> alloc .realloc (api -> alloc .ctx , q - 2 * SST , total );
1538
- if (q == NULL ) {
1539
- return NULL ;
1540
+ tail = data + original_nbytes ;
1541
+ serialno = read_size_t (tail + SST );
1542
+ /* Mark the header, the trailer, ERASED_SIZE bytes at the begin and
1543
+ ERASED_SIZE bytes at the end as dead and save the copy of erased bytes.
1544
+ */
1545
+ if (original_nbytes <= sizeof (save )) {
1546
+ memcpy (save , data , original_nbytes );
1547
+ memset (data - 2 * SST , DEADBYTE , original_nbytes + 4 * SST );
1548
+ }
1549
+ else {
1550
+ memcpy (save , data , ERASED_SIZE );
1551
+ memset (head , DEADBYTE , ERASED_SIZE + 2 * SST );
1552
+ memcpy (& save [ERASED_SIZE ], tail - ERASED_SIZE , ERASED_SIZE );
1553
+ memset (tail - ERASED_SIZE , DEADBYTE , ERASED_SIZE + 2 * SST );
1540
1554
}
1541
1555
1542
- bumpserialno ();
1543
- write_size_t (q , nbytes );
1544
- assert (q [SST ] == (uint8_t )api -> api_id );
1545
- for (i = 1 ; i < SST ; ++ i ) {
1546
- assert (q [SST + i ] == FORBIDDENBYTE );
1556
+ /* Resize and add decorations. */
1557
+ r = (uint8_t * )api -> alloc .realloc (api -> alloc .ctx , head , total );
1558
+ if (r == NULL ) {
1559
+ nbytes = original_nbytes ;
1560
+ }
1561
+ else {
1562
+ head = r ;
1563
+ bumpserialno ();
1564
+ serialno = _PyRuntime .mem .serialno ;
1547
1565
}
1548
- data = q + 2 * SST ;
1566
+
1567
+ write_size_t (head , nbytes );
1568
+ head [SST ] = (uint8_t )api -> api_id ;
1569
+ memset (head + SST + 1 , FORBIDDENBYTE , SST - 1 );
1570
+ data = head + 2 * SST ;
1549
1571
1550
1572
tail = data + nbytes ;
1551
1573
memset (tail , FORBIDDENBYTE , SST );
1552
- write_size_t (tail + SST , _PyRuntime .mem .serialno );
1574
+ write_size_t (tail + SST , serialno );
1575
+
1576
+ /* Restore saved bytes. */
1577
+ if (original_nbytes <= sizeof (save )) {
1578
+ memcpy (data , save , Py_MIN (nbytes , original_nbytes ));
1579
+ }
1580
+ else {
1581
+ size_t i = original_nbytes - ERASED_SIZE ;
1582
+ memcpy (data , save , Py_MIN (nbytes , ERASED_SIZE ));
1583
+ if (nbytes > i ) {
1584
+ memcpy (data + i , & save [ERASED_SIZE ],
1585
+ Py_MIN (nbytes - i , ERASED_SIZE ));
1586
+ }
1587
+ }
1588
+
1589
+ if (r == NULL ) {
1590
+ return NULL ;
1591
+ }
1553
1592
1554
1593
if (nbytes > original_nbytes ) {
1555
1594
/* growing: mark new extra memory clean */
1556
- memset (data + original_nbytes , CLEANBYTE ,
1557
- nbytes - original_nbytes );
1595
+ memset (data + original_nbytes , CLEANBYTE , nbytes - original_nbytes );
1558
1596
}
1559
1597
1560
1598
return data ;
0 commit comments