* alloc.c (check_depth): New variable.
authorJan Djärv <jan.h.d@swipnet.se>
Sat, 25 Dec 2004 10:13:57 +0000 (10:13 +0000)
committerJan Djärv <jan.h.d@swipnet.se>
Sat, 25 Dec 2004 10:13:57 +0000 (10:13 +0000)
(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
src/alloc.c

index 83419a1..3e9034c 100644 (file)
@@ -1,3 +1,12 @@
+2004-12-25  Jan Dj\e,Ad\e(Brv  <jan.h.d@swipnet.se>
+
+       * 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\e,Ad\e(Brv  <jan.h.d@swipnet.se>
 
        * keyboard.c (input_available_signal): Call SIGNAL_THREAD_CHECK
index 83de925..143f5c7 100644 (file)
@@ -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