Add suppression code around calls to original allocation functions to handle things like new[] calling new. b=391491 r+a=brendan
authordbaron@dbaron.org
Fri, 10 Aug 2007 15:22:07 -0700
changeset 4500 ab976c32105f71c18fb759c6ceab9c4ca1fdfc1c
parent 4499 18e747c9e0872f75f9eb868222823c826ba888a8
child 4501 0bf7c9a3cbd987bc1dc703256b1b44859e768081
push idunknown
push userunknown
push dateunknown
bugs391491
milestone1.9a8pre
Add suppression code around calls to original allocation functions to handle things like new[] calling new. b=391491 r+a=brendan
tools/trace-malloc/lib/nsTraceMalloc.c
tools/trace-malloc/lib/nsTraceMallocCallbacks.h
tools/trace-malloc/lib/nsWinTraceMalloc.cpp
--- a/tools/trace-malloc/lib/nsTraceMalloc.c
+++ b/tools/trace-malloc/lib/nsTraceMalloc.c
@@ -44,17 +44,16 @@
  * - extend logfile so 'F' record tells free stack
  * - diagnose rusty's SMP realloc oldsize corruption bug
  * - #ifdef __linux__/x86 and port to other platforms
  * - unify calltree with gc/boehm somehow (common utility lib?)
  */
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
-#include <stdlib.h>
 #include <string.h>
 #ifdef XP_UNIX
 #include <unistd.h>
 #include <sys/stat.h>
 #include <sys/time.h>
 #endif
 #include "plhash.h"
 #include "pratom.h"
@@ -64,23 +63,23 @@
 #include "prprf.h"
 #include "prenv.h"
 #include "prnetdb.h"
 #include "nsTraceMalloc.h"
 #include "nscore.h"
 #include "prinit.h"
 #include "prthread.h"
 #include "nsStackWalk.h"
+#include "nsTraceMallocCallbacks.h"
 
 #ifdef XP_WIN32
 #include <sys/timeb.h>/*for timeb*/
 #include <sys/stat.h>/*for fstat*/
 
 #include <io.h> /*for write*/
-#include "nsTraceMallocCallbacks.h"
 
 #define WRITE_FLAGS "w"
 
 #endif /* WIN32 */
 
 #ifdef XP_UNIX
 #define WRITE_FLAGS "w"
 
@@ -96,22 +95,16 @@ extern __ptr_t __libc_valloc(size_t);
 #ifdef WRAP_SYSTEM_INCLUDES
 #pragma GCC visibility pop
 #endif
 
 #endif /* !XP_UNIX */
 
 #ifdef XP_WIN32
 
-/* defined in nsWinTraceMalloc.cpp */
-void* dhw_orig_malloc(size_t);
-void* dhw_orig_calloc(size_t, size_t);
-void* dhw_orig_realloc(void*, size_t);
-void dhw_orig_free(void*);
-
 #define __libc_malloc(x)                dhw_orig_malloc(x)
 #define __libc_calloc(x, y)             dhw_orig_calloc(x,y)
 #define __libc_realloc(x, y)            dhw_orig_realloc(x,y)
 #define __libc_free(x)                  dhw_orig_free(x)
 
 #endif
 
 typedef struct logfile logfile;
@@ -164,23 +157,16 @@ static int tracing_enabled = 1;
     PR_END_MACRO
 
 #define TM_EXIT_LOCK()                                                        \
     PR_BEGIN_MACRO                                                            \
         if (tmlock)                                                           \
             PR_Unlock(tmlock);                                                \
     PR_END_MACRO
 
-/* Used by backtrace. */
-typedef struct stack_buffer_info {
-    void **buffer;
-    size_t size;
-    size_t entries;
-} stack_buffer_info;
-
 /*
  * Thread-local storage.
  *
  * We can't use NSPR thread-local storage for this because it mallocs
  * within PR_GetThreadPrivate (the first time) and PR_SetThreadPrivate
  * (which can be worked around by protecting all uses of those functions
  * with a monitor, ugh) and because it calls malloc/free when the
  * thread-local storage is in an inconsistent state within
@@ -208,28 +194,16 @@ typedef struct stack_buffer_info {
 #define TM_TLS_INDEX_TYPE               pthread_key_t
 #define TM_CREATE_TLS_INDEX(i_)         pthread_key_create(&(i_), NULL)
 #define TM_DESTROY_TLS_INDEX(i_)        pthread_key_delete((i_))
 #define TM_GET_TLS_DATA(i_)             pthread_getspecific((i_))
 #define TM_SET_TLS_DATA(i_, v_)         pthread_setspecific((i_), (v_))
 
 #endif
 
-typedef struct tm_thread tm_thread;
-struct tm_thread {
-    /*
-     * This counter suppresses tracing, in case any tracing code needs
-     * to malloc.
-     */
-    uint32 suppress_tracing;
-
-    /* buffer for backtrace, below */
-    stack_buffer_info backtrace_buf;
-};
-
 static TM_TLS_INDEX_TYPE tls_index;
 static tm_thread main_thread; /* 0-initialization is correct */
 
 /* FIXME (maybe): This is currently unused; we leak the thread-local data. */
 #if 0
 PR_STATIC_CALLBACK(void)
 free_tm_thread(void *priv)
 {
@@ -242,18 +216,18 @@ free_tm_thread(void *priv)
         if (t->backtrace_buf.buffer)
             __libc_free(t->backtrace_buf.buffer);
 
         __libc_free(t);
     }
 }
 #endif
 
-static tm_thread *
-get_tm_thread(void)
+tm_thread *
+tm_get_thread(void)
 {
     tm_thread *t;
     tm_thread stack_tm_thread;
 
     if (!tmlock) {
         return &main_thread;
     }
 
@@ -1057,17 +1031,17 @@ malloc(size_t size)
     PRUint32 start, end;
     __ptr_t ptr;
     callsite *site;
     PLHashEntry *he;
     allocation *alloc;
     tm_thread *t;
 
     if (!tracing_enabled || !PR_Initialized() ||
-        (t = get_tm_thread())->suppress_tracing != 0) {
+        (t = tm_get_thread())->suppress_tracing != 0) {
         return __libc_malloc(size);
     }
 
     start = PR_IntervalNow();
     ptr = __libc_malloc(size);
     end = PR_IntervalNow();
 
     site = backtrace(t, 1);
@@ -1114,17 +1088,17 @@ calloc(size_t count, size_t size)
      *
      * Thus, our calloc replacement is invoked too early, tries to
      * initialize NSPR, which calls dlopen, which calls into the dl
      * -> crash.
      *
      * Delaying NSPR calls until NSPR is initialized helps.
      */
     if (!tracing_enabled || !PR_Initialized() ||
-        (t = get_tm_thread())->suppress_tracing != 0) {
+        (t = tm_get_thread())->suppress_tracing != 0) {
         return __libc_calloc(count, size);
     }
 
     start = PR_IntervalNow();
     ptr = __libc_calloc(count, size);
     end = PR_IntervalNow();
 
     site = backtrace(t, 1);
@@ -1164,17 +1138,17 @@ realloc(__ptr_t ptr, size_t size)
     size_t oldsize;
     PLHashNumber hash;
     PLHashEntry **hep, *he;
     allocation *alloc;
     FILE *trackfp = NULL;
     tm_thread *t;
 
     if (!tracing_enabled || !PR_Initialized() ||
-        (t = get_tm_thread())->suppress_tracing != 0) {
+        (t = tm_get_thread())->suppress_tracing != 0) {
         return __libc_realloc(ptr, size);
     }
 
     t->suppress_tracing++;
     TM_ENTER_LOCK();
     tmstats.realloc_calls++;
     if (PR_TRUE) {
         oldptr = ptr;
@@ -1263,17 +1237,17 @@ valloc(size_t size)
     PRUint32 start, end;
     __ptr_t ptr;
     callsite *site;
     PLHashEntry *he;
     allocation *alloc;
     tm_thread *t;
 
     if (!tracing_enabled || !PR_Initialized() ||
-        (t = get_tm_thread())->suppress_tracing != 0) {
+        (t = tm_get_thread())->suppress_tracing != 0) {
         return __libc_valloc(size);
     }
 
     start = PR_IntervalNow();
     ptr = __libc_valloc(size);
     end = PR_IntervalNow();
 
     site = backtrace(t, 1);
@@ -1308,17 +1282,17 @@ memalign(size_t boundary, size_t size)
     PRUint32 start, end;
     __ptr_t ptr;
     callsite *site;
     PLHashEntry *he;
     allocation *alloc;
     tm_thread *t;
 
     if (!tracing_enabled || !PR_Initialized() ||
-        (t = get_tm_thread())->suppress_tracing != 0) {
+        (t = tm_get_thread())->suppress_tracing != 0) {
         return __libc_memalign(boundary, size);
     }
 
     start = PR_IntervalNow();
     ptr = __libc_memalign(boundary, size);
     end = PR_IntervalNow();
 
     site = backtrace(t, 1);
@@ -1364,17 +1338,17 @@ free(__ptr_t ptr)
     PLHashEntry **hep, *he;
     callsite *site;
     allocation *alloc;
     uint32 serial = 0, size = 0;
     PRUint32 start, end;
     tm_thread *t;
 
     if (!tracing_enabled || !PR_Initialized() ||
-        (t = get_tm_thread())->suppress_tracing != 0) {
+        (t = tm_get_thread())->suppress_tracing != 0) {
         __libc_free(ptr);
         return;
     }
 
     t->suppress_tracing++;
     TM_ENTER_LOCK();
     tmstats.free_calls++;
     if (!ptr) {
@@ -1656,43 +1630,43 @@ PR_IMPLEMENT(void) NS_TraceMallocShutdow
         ShutdownHooker();
     }
 #endif
 }
 
 PR_IMPLEMENT(void) NS_TraceMallocDisable()
 {
     logfile *fp;
-    tm_thread *t = get_tm_thread();
+    tm_thread *t = tm_get_thread();
 
     t->suppress_tracing++;
     TM_ENTER_LOCK();
     for (fp = logfile_list; fp; fp = fp->next)
         flush_logfile(fp);
     tracing_enabled = 0;
     TM_EXIT_LOCK();
     t->suppress_tracing--;
 }
 
 PR_IMPLEMENT(void) NS_TraceMallocEnable()
 {
-    tm_thread *t = get_tm_thread();
+    tm_thread *t = tm_get_thread();
 
     t->suppress_tracing++;
     TM_ENTER_LOCK();
     tracing_enabled = 1;
     TM_EXIT_LOCK();
     t->suppress_tracing--;
 }
 
 PR_IMPLEMENT(int) NS_TraceMallocChangeLogFD(int fd)
 {
     logfile *oldfp, *fp;
     struct stat sb;
-    tm_thread *t = get_tm_thread();
+    tm_thread *t = tm_get_thread();
 
     t->suppress_tracing++;
     TM_ENTER_LOCK();
     oldfp = logfp;
     if (oldfp->fd != fd) {
         flush_logfile(oldfp);
         fp = get_logfile(fd);
         if (!fp) {
@@ -1728,17 +1702,17 @@ lfd_clr_walk(callsite *site, logfile *fp
     for (kid = site->kids; kid; kid = kid->siblings)
         lfd_clr_walk(kid, fp);
 }
 
 PR_IMPLEMENT(void)
 NS_TraceMallocCloseLogFD(int fd)
 {
     logfile *fp;
-    tm_thread *t = get_tm_thread();
+    tm_thread *t = tm_get_thread();
 
     t->suppress_tracing++;
     TM_ENTER_LOCK();
 
     fp = get_logfile(fd);
     if (fp) {
         flush_logfile(fp);
         if (fp == &default_logfile) {
@@ -1777,17 +1751,17 @@ NS_TraceMallocLogTimestamp(const char *c
 {
     logfile *fp;
 #ifdef XP_UNIX
     struct timeval tv;
 #endif
 #ifdef XP_WIN32
     struct _timeb tb;
 #endif
-    tm_thread *t = get_tm_thread();
+    tm_thread *t = tm_get_thread();
 
     t->suppress_tracing++;
     TM_ENTER_LOCK();
 
     fp = logfp;
     log_byte(fp, TM_EVENT_TIMESTAMP);
 
 #ifdef XP_UNIX
@@ -1836,17 +1810,17 @@ allocation_enumerator(PLHashEntry *he, P
     fputc('\n', ofp);
     return HT_ENUMERATE_NEXT;
 }
 
 PR_IMPLEMENT(void)
 NS_TraceStack(int skip, FILE *ofp)
 {
     callsite *site;
-    tm_thread *t = get_tm_thread();
+    tm_thread *t = tm_get_thread();
 
     site = backtrace(t, skip + 1);
     while (site) {
         if (site->name || site->parent) {
             fprintf(ofp, "%s[%s +0x%X]\n",
                     site->name, site->library, site->offset);
         }
         site = site->parent;
@@ -1867,34 +1841,34 @@ NS_TraceMallocDumpAllocations(const char
     fclose(ofp);
     return rv;
 }
 
 PR_IMPLEMENT(void)
 NS_TraceMallocFlushLogfiles()
 {
     logfile *fp;
-    tm_thread *t = get_tm_thread();
+    tm_thread *t = tm_get_thread();
 
     t->suppress_tracing++;
     TM_ENTER_LOCK();
 
     for (fp = logfile_list; fp; fp = fp->next)
         flush_logfile(fp);
 
     TM_EXIT_LOCK();
     t->suppress_tracing--;
 }
 
 PR_IMPLEMENT(void)
 NS_TrackAllocation(void* ptr, FILE *ofp)
 {
     PLHashEntry **hep;
     allocation *alloc;
-    tm_thread *t = get_tm_thread();
+    tm_thread *t = tm_get_thread();
 
     fprintf(ofp, "Trying to track %p\n", (void*) ptr);
     setlinebuf(ofp);
 
     t->suppress_tracing++;
     TM_ENTER_LOCK();
     if (get_allocations()) {
         hep = PL_HashTableRawLookup(allocations, hash_pointer(ptr), ptr);
@@ -1908,24 +1882,23 @@ NS_TrackAllocation(void* ptr, FILE *ofp)
     }
     TM_EXIT_LOCK();
     t->suppress_tracing--;
 }
 
 #ifdef XP_WIN32
 
 PR_IMPLEMENT(void)
-MallocCallback(void *ptr, size_t size, PRUint32 start, PRUint32 end)
+MallocCallback(void *ptr, size_t size, PRUint32 start, PRUint32 end, tm_thread *t)
 {
     callsite *site;
     PLHashEntry *he;
     allocation *alloc;
-    tm_thread *t;
 
-    if (!tracing_enabled || (t = get_tm_thread())->suppress_tracing != 0)
+    if (!tracing_enabled || t->suppress_tracing != 0)
         return;
 
     site = backtrace(t, 2);
 
     t->suppress_tracing++;
     TM_ENTER_LOCK();
     tmstats.malloc_calls++;
     if (!ptr) {
@@ -1943,24 +1916,23 @@ MallocCallback(void *ptr, size_t size, P
             }
         }
     }
     TM_EXIT_LOCK();
     t->suppress_tracing--;
 }
 
 PR_IMPLEMENT(void)
-CallocCallback(void *ptr, size_t count, size_t size, PRUint32 start, PRUint32 end)
+CallocCallback(void *ptr, size_t count, size_t size, PRUint32 start, PRUint32 end, tm_thread *t)
 {
     callsite *site;
     PLHashEntry *he;
     allocation *alloc;
-    tm_thread *t;
 
-    if (!tracing_enabled || (t = get_tm_thread())->suppress_tracing != 0)
+    if (!tracing_enabled || t->suppress_tracing != 0)
         return;
 
     site = backtrace(t, 2);
 
     t->suppress_tracing++;
     TM_ENTER_LOCK();
     tmstats.calloc_calls++;
     if (!ptr) {
@@ -1979,26 +1951,25 @@ CallocCallback(void *ptr, size_t count, 
             }
         }
     }
     TM_EXIT_LOCK();
     t->suppress_tracing--;
 }
 
 PR_IMPLEMENT(void)
-ReallocCallback(void * oldptr, void *ptr, size_t size, PRUint32 start, PRUint32 end)
+ReallocCallback(void * oldptr, void *ptr, size_t size, PRUint32 start, PRUint32 end, tm_thread *t)
 {
     callsite *oldsite, *site;
     size_t oldsize;
     PLHashNumber hash;
     PLHashEntry **hep, *he;
     allocation *alloc;
-    tm_thread *t;
 
-    if (!tracing_enabled || (t = get_tm_thread())->suppress_tracing != 0)
+    if (!tracing_enabled || t->suppress_tracing != 0)
         return;
 
     site = backtrace(t, 2);
 
     t->suppress_tracing++;
     TM_ENTER_LOCK();
     tmstats.realloc_calls++;
     if (PR_TRUE) {
@@ -2056,24 +2027,23 @@ ReallocCallback(void * oldptr, void *ptr
             }
         }
     }
     TM_EXIT_LOCK();
     t->suppress_tracing--;
 }
 
 PR_IMPLEMENT(void)
-FreeCallback(void * ptr, PRUint32 start, PRUint32 end)
+FreeCallback(void * ptr, PRUint32 start, PRUint32 end, tm_thread *t)
 {
     PLHashEntry **hep, *he;
     callsite *site;
     allocation *alloc;
-    tm_thread *t;
 
-    if (!tracing_enabled || (t = get_tm_thread())->suppress_tracing != 0)
+    if (!tracing_enabled || t->suppress_tracing != 0)
         return;
 
     t->suppress_tracing++;
     TM_ENTER_LOCK();
     tmstats.free_calls++;
     if (!ptr) {
         tmstats.null_free_calls++;
     } else {
--- a/tools/trace-malloc/lib/nsTraceMallocCallbacks.h
+++ b/tools/trace-malloc/lib/nsTraceMallocCallbacks.h
@@ -1,20 +1,93 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Windows port of trace-malloc.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2001
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Michael Judge (original author)
+ *   L. David Baron <dbaron@dbaron.org>, Mozilla Corporation
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* declarations needed by both nsTraceMalloc.c and nsWinTraceMalloc.cpp */
+
 #ifndef NSTRACEMALLOCCALLBACKS_H
 #define NSTRACEMALLOCCALLBACKS_H
 
+#include <stdlib.h>
+
 PR_BEGIN_EXTERN_C
 
+/* Used by backtrace. */
+typedef struct stack_buffer_info {
+    void **buffer;
+    size_t size;
+    size_t entries;
+} stack_buffer_info;
 
-PR_EXTERN(void) StartupHooker();/*implemented in TraceMalloc.cpp*/
+typedef struct tm_thread tm_thread;
+struct tm_thread {
+    /*
+     * This counter suppresses tracing, in case any tracing code needs
+     * to malloc.
+     */
+    uint32 suppress_tracing;
+
+    /* buffer for backtrace, below */
+    stack_buffer_info backtrace_buf;
+};
+
+/* implemented in nsTraceMalloc.c */
+tm_thread * tm_get_thread(void);
+
+#ifdef XP_WIN32
+/* implemented in nsTraceMalloc.c */
+PR_EXTERN(void) StartupHooker();
 PR_EXTERN(void) ShutdownHooker();
 
-PR_EXTERN(void) MallocCallback(void *aPtr, size_t aSize, PRUint32 start, PRUint32 end);/*implemented in nsTraceMalloc.c*/
-PR_EXTERN(void) CallocCallback(void *aPtr, size_t aCount, size_t aSize, PRUint32 start, PRUint32 end);
-PR_EXTERN(void) ReallocCallback(void *aPin, void* aPout, size_t aSize, PRUint32 start, PRUint32 end);
-PR_EXTERN(void) FreeCallback(void *aPtr, PRUint32 start, PRUint32 end);
+/* implemented in nsTraceMalloc.c */
+PR_EXTERN(void) MallocCallback(void *aPtr, size_t aSize, PRUint32 start, PRUint32 end, tm_thread *t);
+PR_EXTERN(void) CallocCallback(void *aPtr, size_t aCount, size_t aSize, PRUint32 start, PRUint32 end, tm_thread *t);
+PR_EXTERN(void) ReallocCallback(void *aPin, void* aPout, size_t aSize, PRUint32 start, PRUint32 end, tm_thread *t);
+PR_EXTERN(void) FreeCallback(void *aPtr, PRUint32 start, PRUint32 end, tm_thread *t);
 
+/* implemented in nsWinTraceMalloc.cpp */
+void* dhw_orig_malloc(size_t);
+void* dhw_orig_calloc(size_t, size_t);
+void* dhw_orig_realloc(void*, size_t);
+void dhw_orig_free(void*);
+
+#endif /* defined(XP_WIN32) */
 
 PR_END_EXTERN_C
 
-
-#endif //NSTRACEMALLOCCALLBACKS_H
-
+#endif /* !defined(NSTRACEMALLOCCALLBACKS_H) */
--- a/tools/trace-malloc/lib/nsWinTraceMalloc.cpp
+++ b/tools/trace-malloc/lib/nsWinTraceMalloc.cpp
@@ -1,8 +1,47 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Windows port of trace-malloc.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2001
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Michael Judge (original author)
+ *   L. David Baron <dbaron@dbaron.org>, Mozilla Corporation
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
 
 #include <stdio.h>
 #include <stdlib.h>
 
 #include "prtypes.h"
 #include "prlock.h"
 #include "nscore.h"
 #include "nsAutoLock.h"
@@ -32,136 +71,160 @@ DHW_DECLARE_FUN_TYPE_AND_PROTO(dhw_mallo
 DHWImportHooker &getMallocHooker()
 {
   static DHWImportHooker gMallocHooker(NS_DEBUG_CRT, "malloc", (PROC) dhw_malloc);
   return gMallocHooker;
 }
 
 void * __cdecl dhw_malloc( size_t size )
 {
+    tm_thread *t = tm_get_thread();
+    ++t->suppress_tracing;
     PRUint32 start = PR_IntervalNow();
     void* result = DHW_ORIGINAL(MALLOC_, getMallocHooker())(size);
     PRUint32 end = PR_IntervalNow();
-    MallocCallback(result, size, start, end);
+    --t->suppress_tracing;
+    MallocCallback(result, size, start, end, t);
     return result;    
 }
 
 DHW_DECLARE_FUN_TYPE_AND_PROTO(dhw_calloc, void*, __cdecl, CALLOC_, (size_t,size_t));
 
 DHWImportHooker &getCallocHooker()
 {
   static DHWImportHooker gCallocHooker(NS_DEBUG_CRT, "calloc", (PROC) dhw_calloc);
   return gCallocHooker;
 }
 
 void * __cdecl dhw_calloc( size_t count, size_t size )
 {
+    tm_thread *t = tm_get_thread();
+    ++t->suppress_tracing;
     PRUint32 start = PR_IntervalNow();
     void* result = DHW_ORIGINAL(CALLOC_, getCallocHooker())(count,size);
     PRUint32 end = PR_IntervalNow();
-    CallocCallback(result, count, size, start, end);
+    --t->suppress_tracing;
+    CallocCallback(result, count, size, start, end, t);
     return result;    
 }
 
 DHW_DECLARE_FUN_TYPE_AND_PROTO(dhw_free, void, __cdecl, FREE_, (void*));
 DHWImportHooker &getFreeHooker()
 {
   static DHWImportHooker gFreeHooker(NS_DEBUG_CRT, "free", (PROC) dhw_free);
   return gFreeHooker;
 }
 
 void __cdecl dhw_free( void* p )
 {
+    tm_thread *t = tm_get_thread();
+    ++t->suppress_tracing;
     PRUint32 start = PR_IntervalNow();
     DHW_ORIGINAL(FREE_, getFreeHooker())(p);
     PRUint32 end = PR_IntervalNow();
-    FreeCallback(p, start, end);
+    --t->suppress_tracing;
+    FreeCallback(p, start, end, t);
 }
 
 
 DHW_DECLARE_FUN_TYPE_AND_PROTO(dhw_realloc, void*, __cdecl, REALLOC_, (void*, size_t));
 DHWImportHooker &getReallocHooker()
 {
   static DHWImportHooker gReallocHooker(NS_DEBUG_CRT, "realloc", (PROC) dhw_realloc);
   return gReallocHooker;
 }
 
 void * __cdecl dhw_realloc(void * pin, size_t size)
 {
+    tm_thread *t = tm_get_thread();
+    ++t->suppress_tracing;
     PRUint32 start = PR_IntervalNow();
     void* pout = DHW_ORIGINAL(REALLOC_, getReallocHooker())(pin, size);
     PRUint32 end = PR_IntervalNow();
-    ReallocCallback(pin, pout, size, start, end);
+    --t->suppress_tracing;
+    ReallocCallback(pin, pout, size, start, end, t);
     return pout;
 }
 
 // Note the mangled name!
 DHW_DECLARE_FUN_TYPE_AND_PROTO(dhw_new, void*, __cdecl, NEW_, (size_t));
 DHWImportHooker &getNewHooker()
 {
   static DHWImportHooker gNewHooker(NS_DEBUG_CRT, "??2@YAPAXI@Z", (PROC) dhw_new);
   return gNewHooker;
 }
 
 void * __cdecl dhw_new(size_t size)
 {
+    tm_thread *t = tm_get_thread();
+    ++t->suppress_tracing;
     PRUint32 start = PR_IntervalNow();
     void* result = DHW_ORIGINAL(NEW_, getNewHooker())(size);
     PRUint32 end = PR_IntervalNow();
-    MallocCallback(result, size, start, end);//do we need a different one for new?
+    --t->suppress_tracing;
+    MallocCallback(result, size, start, end, t);//do we need a different one for new?
     return result;
 }
 
 // Note the mangled name!
 DHW_DECLARE_FUN_TYPE_AND_PROTO(dhw_delete, void, __cdecl, DELETE_, (void*));
 DHWImportHooker &getDeleteHooker()
 {
   static DHWImportHooker gDeleteHooker(NS_DEBUG_CRT, "??3@YAXPAX@Z", (PROC) dhw_delete);
   return gDeleteHooker;
 }
 
 void __cdecl dhw_delete(void* p)
 {
+    tm_thread *t = tm_get_thread();
+    ++t->suppress_tracing;
     PRUint32 start = PR_IntervalNow();
     DHW_ORIGINAL(DELETE_, getDeleteHooker())(p);
     PRUint32 end = PR_IntervalNow();
-    FreeCallback(p, start, end);
+    --t->suppress_tracing;
+    FreeCallback(p, start, end, t);
 }
 
 // Note the mangled name!
 DHW_DECLARE_FUN_TYPE_AND_PROTO(dhw_vec_new, void*, __cdecl, VEC_NEW_, (size_t));
 DHWImportHooker &getVecNewHooker()
 {
   static DHWImportHooker gVecNewHooker(NS_DEBUG_CRT, "??_U@YAPAXI@Z", (PROC) dhw_vec_new);
   return gVecNewHooker;
 }
 
 void * __cdecl dhw_vec_new(size_t size)
 {
+    tm_thread *t = tm_get_thread();
+    ++t->suppress_tracing; // need to suppress since new[] calls new
     PRUint32 start = PR_IntervalNow();
     void* result = DHW_ORIGINAL(VEC_NEW_, getVecNewHooker())(size);
     PRUint32 end = PR_IntervalNow();
-    MallocCallback(result, size, start, end);//do we need a different one for new[]?
+    --t->suppress_tracing;
+    MallocCallback(result, size, start, end, t);//do we need a different one for new[]?
     return result;
 }
 
 // Note the mangled name!
 DHW_DECLARE_FUN_TYPE_AND_PROTO(dhw_vec_delete, void, __cdecl, VEC_DELETE_, (void*));
 DHWImportHooker &getVecDeleteHooker()
 {
   static DHWImportHooker gVecDeleteHooker(NS_DEBUG_CRT, "??_V@YAXPAX@Z", (PROC) dhw_vec_delete);
   return gVecDeleteHooker;
 }
 
 void __cdecl dhw_vec_delete(void* p)
 {
+    tm_thread *t = tm_get_thread();
+    ++t->suppress_tracing;
     PRUint32 start = PR_IntervalNow();
     DHW_ORIGINAL(VEC_DELETE_, getVecDeleteHooker())(p);
     PRUint32 end = PR_IntervalNow();
-    FreeCallback(p, start, end);
+    --t->suppress_tracing;
+    FreeCallback(p, start, end, t);
 }
 
 /*C Callbacks*/
 PR_IMPLEMENT(void)
 StartupHooker()
 {
   //run through get all hookers
   DHWImportHooker &loadlibraryW = DHWImportHooker::getLoadLibraryWHooker();