From 857ae68b96103b3a8a7116f8d14a13d1623be4d5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jan=20Dj=C3=A4rv?= Date: Sat, 25 Dec 2004 10:13:57 +0000 Subject: [PATCH] * 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. --- src/ChangeLog | 9 +++++++++ src/alloc.c | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 83419a166a..3e9034c626 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,12 @@ +2004-12-25 Jan Dj,Ad(Brv + + * 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. + 2004-12-23 Jan Dj,Ad(Brv * keyboard.c (input_available_signal): Call SIGNAL_THREAD_CHECK diff --git a/src/alloc.c b/src/alloc.c index 83de92520c..143f5c7629 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -601,6 +601,25 @@ static char xmalloc_overrun_check_trailer[XMALLOC_OVERRUN_CHECK_SIZE] = ((unsigned)(ptr[-4]) << 24)) +/* The call depth in overrun_check functions. Realloc may call both malloc + and free. If realloc calls malloc, this may happen: + overrun_check_realloc() + -> malloc -> (via hook)_-> emacs_blocked_malloc + -> overrun_check_malloc + call malloc (hooks are NULL, so real malloc is called). + malloc returns 10000. + add overhead, return 10016. + <- (back in overrun_check_realloc) + add overhead again, return 10032 + + (time passes). + + overrun_check_free(10032) + decrease overhed + free(10016) <- crash, because 10000 is the original pointer. */ + +static int check_depth; + /* Like malloc, but wraps allocated block with header and trailer. */ POINTER_TYPE * @@ -608,15 +627,17 @@ overrun_check_malloc (size) size_t size; { register unsigned char *val; + size_t overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_SIZE*2 : 0; - val = (unsigned char *) malloc (size + XMALLOC_OVERRUN_CHECK_SIZE*2); - if (val) + val = (unsigned char *) malloc (size + overhead); + if (val && check_depth == 1) { bcopy (xmalloc_overrun_check_header, val, XMALLOC_OVERRUN_CHECK_SIZE - 4); val += XMALLOC_OVERRUN_CHECK_SIZE; XMALLOC_PUT_SIZE(val, size); bcopy (xmalloc_overrun_check_trailer, val + size, XMALLOC_OVERRUN_CHECK_SIZE); } + --check_depth; return (POINTER_TYPE *)val; } @@ -630,8 +651,10 @@ overrun_check_realloc (block, size) size_t size; { register unsigned char *val = (unsigned char *)block; + size_t overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_SIZE*2 : 0; if (val + && check_depth == 1 && bcmp (xmalloc_overrun_check_header, val - XMALLOC_OVERRUN_CHECK_SIZE, XMALLOC_OVERRUN_CHECK_SIZE - 4) == 0) @@ -646,15 +669,16 @@ overrun_check_realloc (block, size) bzero (val, XMALLOC_OVERRUN_CHECK_SIZE); } - val = (unsigned char *) realloc ((POINTER_TYPE *)val, size + XMALLOC_OVERRUN_CHECK_SIZE*2); + val = (unsigned char *) realloc ((POINTER_TYPE *)val, size + overhead); - if (val) + if (val && check_depth == 1) { bcopy (xmalloc_overrun_check_header, val, XMALLOC_OVERRUN_CHECK_SIZE - 4); val += XMALLOC_OVERRUN_CHECK_SIZE; XMALLOC_PUT_SIZE(val, size); bcopy (xmalloc_overrun_check_trailer, val + size, XMALLOC_OVERRUN_CHECK_SIZE); } + --check_depth; return (POINTER_TYPE *)val; } @@ -666,7 +690,9 @@ overrun_check_free (block) { unsigned char *val = (unsigned char *)block; + ++check_depth; if (val + && check_depth == 1 && bcmp (xmalloc_overrun_check_header, val - XMALLOC_OVERRUN_CHECK_SIZE, XMALLOC_OVERRUN_CHECK_SIZE - 4) == 0) @@ -682,6 +708,7 @@ overrun_check_free (block) } free (val); + --check_depth; } #undef malloc -- 2.20.1