diff options
| author | Jan Djärv | 2004-12-25 10:13:57 +0000 |
|---|---|---|
| committer | Jan Djärv | 2004-12-25 10:13:57 +0000 |
| commit | 857ae68b96103b3a8a7116f8d14a13d1623be4d5 (patch) | |
| tree | 8bb55aa3c45483166729f63f2780ca8734b49ee2 /src/alloc.c | |
| parent | 70d16390a08dc9d94c961eb380be8e1b5b496963 (diff) | |
| download | emacs-857ae68b96103b3a8a7116f8d14a13d1623be4d5.tar.gz emacs-857ae68b96103b3a8a7116f8d14a13d1623be4d5.zip | |
* alloc.c (check_depth): New variable.
(overrun_check_malloc, overrun_check_realloc): Only add
overhead and write check pattern if check_depth is 1 (to handle
recursive calls). Increase/decrease check_depth in entry/exit.
(overrun_check_free): Only check for overhead if check_depth is 1.
Increase/decrease check_depth in entry/exit.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/src/alloc.c b/src/alloc.c index 83de92520c4..143f5c76292 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -601,6 +601,25 @@ static char xmalloc_overrun_check_trailer[XMALLOC_OVERRUN_CHECK_SIZE] = | |||
| 601 | ((unsigned)(ptr[-4]) << 24)) | 601 | ((unsigned)(ptr[-4]) << 24)) |
| 602 | 602 | ||
| 603 | 603 | ||
| 604 | /* The call depth in overrun_check functions. Realloc may call both malloc | ||
| 605 | and free. If realloc calls malloc, this may happen: | ||
| 606 | overrun_check_realloc() | ||
| 607 | -> malloc -> (via hook)_-> emacs_blocked_malloc | ||
| 608 | -> overrun_check_malloc | ||
| 609 | call malloc (hooks are NULL, so real malloc is called). | ||
| 610 | malloc returns 10000. | ||
| 611 | add overhead, return 10016. | ||
| 612 | <- (back in overrun_check_realloc) | ||
| 613 | add overhead again, return 10032 | ||
| 614 | |||
| 615 | (time passes). | ||
| 616 | |||
| 617 | overrun_check_free(10032) | ||
| 618 | decrease overhed | ||
| 619 | free(10016) <- crash, because 10000 is the original pointer. */ | ||
| 620 | |||
| 621 | static int check_depth; | ||
| 622 | |||
| 604 | /* Like malloc, but wraps allocated block with header and trailer. */ | 623 | /* Like malloc, but wraps allocated block with header and trailer. */ |
| 605 | 624 | ||
| 606 | POINTER_TYPE * | 625 | POINTER_TYPE * |
| @@ -608,15 +627,17 @@ overrun_check_malloc (size) | |||
| 608 | size_t size; | 627 | size_t size; |
| 609 | { | 628 | { |
| 610 | register unsigned char *val; | 629 | register unsigned char *val; |
| 630 | size_t overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_SIZE*2 : 0; | ||
| 611 | 631 | ||
| 612 | val = (unsigned char *) malloc (size + XMALLOC_OVERRUN_CHECK_SIZE*2); | 632 | val = (unsigned char *) malloc (size + overhead); |
| 613 | if (val) | 633 | if (val && check_depth == 1) |
| 614 | { | 634 | { |
| 615 | bcopy (xmalloc_overrun_check_header, val, XMALLOC_OVERRUN_CHECK_SIZE - 4); | 635 | bcopy (xmalloc_overrun_check_header, val, XMALLOC_OVERRUN_CHECK_SIZE - 4); |
| 616 | val += XMALLOC_OVERRUN_CHECK_SIZE; | 636 | val += XMALLOC_OVERRUN_CHECK_SIZE; |
| 617 | XMALLOC_PUT_SIZE(val, size); | 637 | XMALLOC_PUT_SIZE(val, size); |
| 618 | bcopy (xmalloc_overrun_check_trailer, val + size, XMALLOC_OVERRUN_CHECK_SIZE); | 638 | bcopy (xmalloc_overrun_check_trailer, val + size, XMALLOC_OVERRUN_CHECK_SIZE); |
| 619 | } | 639 | } |
| 640 | --check_depth; | ||
| 620 | return (POINTER_TYPE *)val; | 641 | return (POINTER_TYPE *)val; |
| 621 | } | 642 | } |
| 622 | 643 | ||
| @@ -630,8 +651,10 @@ overrun_check_realloc (block, size) | |||
| 630 | size_t size; | 651 | size_t size; |
| 631 | { | 652 | { |
| 632 | register unsigned char *val = (unsigned char *)block; | 653 | register unsigned char *val = (unsigned char *)block; |
| 654 | size_t overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_SIZE*2 : 0; | ||
| 633 | 655 | ||
| 634 | if (val | 656 | if (val |
| 657 | && check_depth == 1 | ||
| 635 | && bcmp (xmalloc_overrun_check_header, | 658 | && bcmp (xmalloc_overrun_check_header, |
| 636 | val - XMALLOC_OVERRUN_CHECK_SIZE, | 659 | val - XMALLOC_OVERRUN_CHECK_SIZE, |
| 637 | XMALLOC_OVERRUN_CHECK_SIZE - 4) == 0) | 660 | XMALLOC_OVERRUN_CHECK_SIZE - 4) == 0) |
| @@ -646,15 +669,16 @@ overrun_check_realloc (block, size) | |||
| 646 | bzero (val, XMALLOC_OVERRUN_CHECK_SIZE); | 669 | bzero (val, XMALLOC_OVERRUN_CHECK_SIZE); |
| 647 | } | 670 | } |
| 648 | 671 | ||
| 649 | val = (unsigned char *) realloc ((POINTER_TYPE *)val, size + XMALLOC_OVERRUN_CHECK_SIZE*2); | 672 | val = (unsigned char *) realloc ((POINTER_TYPE *)val, size + overhead); |
| 650 | 673 | ||
| 651 | if (val) | 674 | if (val && check_depth == 1) |
| 652 | { | 675 | { |
| 653 | bcopy (xmalloc_overrun_check_header, val, XMALLOC_OVERRUN_CHECK_SIZE - 4); | 676 | bcopy (xmalloc_overrun_check_header, val, XMALLOC_OVERRUN_CHECK_SIZE - 4); |
| 654 | val += XMALLOC_OVERRUN_CHECK_SIZE; | 677 | val += XMALLOC_OVERRUN_CHECK_SIZE; |
| 655 | XMALLOC_PUT_SIZE(val, size); | 678 | XMALLOC_PUT_SIZE(val, size); |
| 656 | bcopy (xmalloc_overrun_check_trailer, val + size, XMALLOC_OVERRUN_CHECK_SIZE); | 679 | bcopy (xmalloc_overrun_check_trailer, val + size, XMALLOC_OVERRUN_CHECK_SIZE); |
| 657 | } | 680 | } |
| 681 | --check_depth; | ||
| 658 | return (POINTER_TYPE *)val; | 682 | return (POINTER_TYPE *)val; |
| 659 | } | 683 | } |
| 660 | 684 | ||
| @@ -666,7 +690,9 @@ overrun_check_free (block) | |||
| 666 | { | 690 | { |
| 667 | unsigned char *val = (unsigned char *)block; | 691 | unsigned char *val = (unsigned char *)block; |
| 668 | 692 | ||
| 693 | ++check_depth; | ||
| 669 | if (val | 694 | if (val |
| 695 | && check_depth == 1 | ||
| 670 | && bcmp (xmalloc_overrun_check_header, | 696 | && bcmp (xmalloc_overrun_check_header, |
| 671 | val - XMALLOC_OVERRUN_CHECK_SIZE, | 697 | val - XMALLOC_OVERRUN_CHECK_SIZE, |
| 672 | XMALLOC_OVERRUN_CHECK_SIZE - 4) == 0) | 698 | XMALLOC_OVERRUN_CHECK_SIZE - 4) == 0) |
| @@ -682,6 +708,7 @@ overrun_check_free (block) | |||
| 682 | } | 708 | } |
| 683 | 709 | ||
| 684 | free (val); | 710 | free (val); |
| 711 | --check_depth; | ||
| 685 | } | 712 | } |
| 686 | 713 | ||
| 687 | #undef malloc | 714 | #undef malloc |