From 00f8bb71ce63d06d3af2e691db44fed52e3fea99 Mon Sep 17 00:00:00 2001 From: "blythe%netscape.com" Date: Thu, 6 Dec 2001 02:36:02 +0000 Subject: [PATCH] Bug 112953, non debug trace-malloc on win32. r=dp,sr=brendan NOT part of normal build. Change hinges on another change to nsprpub/gmakefile.win that should land by those in charge of that module shortly. git-svn-id: svn://10.0.0.236/trunk@109789 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/config/WIN32 | 16 +++- mozilla/embedding/tests/mfcembed/StdAfx.h | 23 +++++- .../tests/mfcembed/components/stdafx.h | 17 +++++ .../tools/trace-malloc/lib/nsTraceMalloc.c | 76 +++++++++++++------ mozilla/xpcom/base/makefile.win | 6 +- mozilla/xpcom/base/nsTraceMalloc.c | 76 +++++++++++++------ mozilla/xpcom/build/makefile.win | 2 +- 7 files changed, 156 insertions(+), 60 deletions(-) diff --git a/mozilla/config/WIN32 b/mozilla/config/WIN32 index a73e09aa697..bccdaa99fec 100644 --- a/mozilla/config/WIN32 +++ b/mozilla/config/WIN32 @@ -90,6 +90,16 @@ OPTIMIZER=-Zi -O1 -UDEBUG -DNDEBUG !endif # MOZ_COVERAGE +# +# Handle trace-malloc in optimized builds. +# No opt to give sane callstacks. +# +!if defined(MOZ_TRACE_MALLOC) +OPTIMIZER=-Zi -Od -UDEBUG -DNDEBUG +OS_LFLAGS=/DEBUG /DEBUGTYPE:CV /PDB:NONE /OPT:REF /OPT:nowin98 +!endif +# MOZ_TRACE_MALLOC + # if MOZ_DEBUG is not set and MOZ_MAPINFO !if defined (MOZ_MAPINFO) OS_LFLAGS=$(OS_LFLAGS) /MAP:$(MAPFILE) /MAPINFO:LINES @@ -115,20 +125,20 @@ OS_LFLAGS= $(OS_LFLAGS) /COD:$(CODFILE) #//------------------------------------------------------------------------ !ifdef USE_STATIC_LIBS RTL_FLAGS=-MT # Statically linked multithreaded RTL -!ifdef MOZ_DEBUG +!if defined(MOZ_DEBUG) || defined(MOZ_TRACE_MALLOC) RTL_FLAGS=-MTd # Statically linked multithreaded MSVC4.0 debug RTL !endif !else ifdef USE_NON_MT_LIBS RTL_FLAGS=-ML # Statically linked non-multithreaded LIBC RTL -!ifdef MOZ_DEBUG +!if defined(MOZ_DEBUG) || defined(MOZ_TRACE_MALLOC) RTL_FLAGS=-MLd # Statically linked non-multithreaded LIBC debug RTL !endif !else RTL_FLAGS=-MD # Dynamically linked, multithreaded RTL -!ifdef MOZ_DEBUG +!if defined(MOZ_DEBUG) || defined(MOZ_TRACE_MALLOC) !ifndef MOZ_NO_DEBUG_RTL RTL_FLAGS=-MDd # Dynamically linked, multithreaded MSVC4.0 debug RTL !endif diff --git a/mozilla/embedding/tests/mfcembed/StdAfx.h b/mozilla/embedding/tests/mfcembed/StdAfx.h index 945e561f5f1..4ada349317c 100644 --- a/mozilla/embedding/tests/mfcembed/StdAfx.h +++ b/mozilla/embedding/tests/mfcembed/StdAfx.h @@ -51,6 +51,19 @@ #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers +// +// These headers are very evil, as they will define DEBUG if _DEBUG is +// defined, which is lame and not what we want for things like +// MOZ_TRACE_MALLOC and other tools. +// If we do not detect this, various MOZ/NS debug symbols are undefined +// and we can not build. +// /MDd defines _DEBUG automagically to have the right debug C LIB +// functions get called (so we can get symbols and hook into malloc). +// +#if !defined(DEBUG) +#define THERECANBENODEBUG +#endif + #include // MFC core and standard components #include // MFC extensions #include // MFC support for Internet Explorer 4 Common Controls @@ -59,6 +72,13 @@ #include // MFC support for Windows Common Controls #endif // _AFX_NO_AFXCMN_SUPPORT +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#if defined(THERECANBENODEBUG) && defined(DEBUG) +#undef DEBUG +#endif + #include "nsCOMPtr.h" #include "nsNetUtil.h" #include "nsString.h" @@ -108,7 +128,4 @@ #include "nsIWebBrowserPrint.h" #include "nsIDOMWindow.h" -//{{AFX_INSERT_LOCATION}} -// Microsoft Visual C++ will insert additional declarations immediately before the previous line. - #endif //_STDAFX_H diff --git a/mozilla/embedding/tests/mfcembed/components/stdafx.h b/mozilla/embedding/tests/mfcembed/components/stdafx.h index b171042519d..0964b529060 100644 --- a/mozilla/embedding/tests/mfcembed/components/stdafx.h +++ b/mozilla/embedding/tests/mfcembed/components/stdafx.h @@ -47,6 +47,19 @@ #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers +// +// These headers are very evil, as they will define DEBUG if _DEBUG is +// defined, which is lame and not what we want for things like +// MOZ_TRACE_MALLOC and other tools. +// If we do not detect this, various MOZ/NS debug symbols are undefined +// and we can not build. +// /MDd defines _DEBUG automagically to have the right debug C LIB +// functions get called (so we can get symbols and hook into malloc). +// +#if !defined(DEBUG) +#define THERECANBENODEBUG +#endif + #include // MFC core and standard components #include // MFC extensions #include // MFC support for Internet Explorer 4 Common Controls @@ -58,4 +71,8 @@ //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. +#if defined(THERECANBENODEBUG) && defined(DEBUG) +#undef DEBUG +#endif + #endif //_STDAFX_H diff --git a/mozilla/tools/trace-malloc/lib/nsTraceMalloc.c b/mozilla/tools/trace-malloc/lib/nsTraceMalloc.c index e5a76552182..e3d9bf6ff84 100644 --- a/mozilla/tools/trace-malloc/lib/nsTraceMalloc.c +++ b/mozilla/tools/trace-malloc/lib/nsTraceMalloc.c @@ -653,8 +653,10 @@ BOOL SymGetModuleInfoEspecial(HANDLE aProcess, DWORD aAddr, PIMAGEHLP_MODULE aMo return retval; } - -#define MAX_STACKFRAMES 256 +/* + * Realease builds seem to take more stackframes. + */ +#define MAX_STACKFRAMES 512 #define MAX_UNMANGLED_NAME_LEN 256 static callsite *calltree(int skip) @@ -664,12 +666,14 @@ static callsite *calltree(int skip) HANDLE myThread; CONTEXT context; int ok, maxstack, offset; + int getSymRes = 0; STACKFRAME frame[MAX_STACKFRAMES]; uint32 library_serial, method_serial; int framenum; uint32 pc; uint32 depth, nkids; - callsite *parent, *site, **csp, *tmp; + callsite *parent, **csp, *tmp; + callsite *site = NULL; char *demangledname; const char *library; IMAGEHLP_MODULE imagehelp; @@ -679,6 +683,7 @@ static callsite *calltree(int skip) PLHashNumber hash; PLHashEntry **hep, *he; lfdset_entry *le; + char* noname = "noname"; imagehelp.SizeOfStruct = sizeof(imagehelp); framenum = 0; @@ -707,7 +712,7 @@ static callsite *calltree(int skip) frame[0].AddrStack.Mode = AddrModeFlat; frame[0].AddrFrame.Offset = context.Ebp; frame[0].AddrFrame.Mode = AddrModeFlat; - for (;;) { + for (;framenum < MAX_STACKFRAMES;) { PIMAGEHLP_SYMBOL symbol = (PIMAGEHLP_SYMBOL) buf; if (framenum) memcpy(&(frame[framenum]),&(frame[framenum-1]),sizeof(STACKFRAME)); @@ -731,7 +736,13 @@ static callsite *calltree(int skip) } if (frame[framenum].AddrPC.Offset == 0) break; + framenum++; + + /* + * Time to increase the number of stack frames? + */ + PR_ASSERT(framenum < MAX_STACKFRAMES); } depth = framenum; @@ -741,7 +752,7 @@ static callsite *calltree(int skip) /* Reverse the stack again, finding and building a path in the tree. */ parent = &calltree_root; - do { + while (0 < framenum) { DWORD displacement;/*used for getsymfromaddr*/ pc = frame[--framenum].AddrPC.Offset; @@ -795,21 +806,11 @@ static callsite *calltree(int skip) if (!SymGetModuleInfoEspecial(myProcess, frame[framenum].AddrPC.Offset, &imagehelp)) { - library = "unknown"; + library = noname; } else { library = imagehelp.ModuleName; } - symbol = (PIMAGEHLP_SYMBOL) buf; - symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL); - symbol->MaxNameLength = sizeof(buf) - sizeof(IMAGEHLP_SYMBOL); - symbol->Name[symbol->MaxNameLength] = '\0'; - - ok = _SymGetSymFromAddr(myProcess, - frame[framenum].AddrPC.Offset, - &displacement, - symbol); - /* Check whether we need to emit a library trace record. */ library_serial = 0; if (library) { @@ -857,12 +858,31 @@ static callsite *calltree(int skip) } } + symbol = (PIMAGEHLP_SYMBOL) buf; + symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL); + symbol->MaxNameLength = sizeof(buf) - sizeof(IMAGEHLP_SYMBOL); + symbol->Name[symbol->MaxNameLength] = '\0'; + + getSymRes = _SymGetSymFromAddr(myProcess, + frame[framenum].AddrPC.Offset, + &displacement, + symbol); + /* Now find the demangled method name and pc offset in it. */ - demangledname = (char *)malloc(MAX_UNMANGLED_NAME_LEN); - if (!_SymUnDName(symbol,demangledname,MAX_UNMANGLED_NAME_LEN)) - return 0; - method = demangledname; - offset = (char*)pc - (char*)(symbol->Address); + if (0 != getSymRes) { + demangledname = (char *)malloc(MAX_UNMANGLED_NAME_LEN); + if (!_SymUnDName(symbol,demangledname,MAX_UNMANGLED_NAME_LEN)) { + free(demangledname); + return 0; + } + method = demangledname; + offset = (char*)pc - (char*)(symbol->Address); + } + else { + method = noname; + offset = pc; + } + /* Emit an 'N' (for New method, 'M' is for malloc!) event if needed. */ method_serial = 0; if (!methods) { @@ -871,7 +891,9 @@ static callsite *calltree(int skip) &lfdset_hashallocops, NULL); if (!methods) { tmstats.btmalloc_failures++; - free((void*) method); + if (method != noname) { + free((void*) method); + } return NULL; } } @@ -880,7 +902,9 @@ static callsite *calltree(int skip) he = *hep; if (he) { method_serial = (uint32) he->value; - free((void*) method); + if (method != noname) { + free((void*) method); + } method = (char *) he->key; le = (lfdset_entry *) he; if (LFD_TEST(fp->lfd, &le->lfdset)) { @@ -893,7 +917,9 @@ static callsite *calltree(int skip) (void*) method_serial); if (!he) { tmstats.btmalloc_failures++; - free((void*) method); + if (method != noname) { + free((void*) method); + } return NULL; } le = (lfdset_entry *) he; @@ -943,7 +969,7 @@ static callsite *calltree(int skip) upward: parent = site; - } while (framenum); + } if (maxstack) calltree_maxstack_top = site; diff --git a/mozilla/xpcom/base/makefile.win b/mozilla/xpcom/base/makefile.win index 2c82599dafa..45c54b2acf9 100644 --- a/mozilla/xpcom/base/makefile.win +++ b/mozilla/xpcom/base/makefile.win @@ -56,7 +56,7 @@ EXPORTS = \ nscore.h \ pure.h \ !ifdef MOZ_TRACE_MALLOC - nsTraceMalloc.h \ + nsTraceMalloc.h \ !endif nsIInterfaceRequestorUtils.h \ $(NULL) @@ -98,8 +98,8 @@ LCFLAGS = $(LCFLAGS) -DGC_LEAK_DETECTOR !ifdef MOZ_TRACE_MALLOC -C_OBJS = \ - .\$(OBJDIR)\nsTraceMalloc.obj \ +C_OBJS = $(C_OBJS) \ + .\$(OBJDIR)\nsTraceMalloc.obj \ $(NULL) !endif diff --git a/mozilla/xpcom/base/nsTraceMalloc.c b/mozilla/xpcom/base/nsTraceMalloc.c index e5a76552182..e3d9bf6ff84 100644 --- a/mozilla/xpcom/base/nsTraceMalloc.c +++ b/mozilla/xpcom/base/nsTraceMalloc.c @@ -653,8 +653,10 @@ BOOL SymGetModuleInfoEspecial(HANDLE aProcess, DWORD aAddr, PIMAGEHLP_MODULE aMo return retval; } - -#define MAX_STACKFRAMES 256 +/* + * Realease builds seem to take more stackframes. + */ +#define MAX_STACKFRAMES 512 #define MAX_UNMANGLED_NAME_LEN 256 static callsite *calltree(int skip) @@ -664,12 +666,14 @@ static callsite *calltree(int skip) HANDLE myThread; CONTEXT context; int ok, maxstack, offset; + int getSymRes = 0; STACKFRAME frame[MAX_STACKFRAMES]; uint32 library_serial, method_serial; int framenum; uint32 pc; uint32 depth, nkids; - callsite *parent, *site, **csp, *tmp; + callsite *parent, **csp, *tmp; + callsite *site = NULL; char *demangledname; const char *library; IMAGEHLP_MODULE imagehelp; @@ -679,6 +683,7 @@ static callsite *calltree(int skip) PLHashNumber hash; PLHashEntry **hep, *he; lfdset_entry *le; + char* noname = "noname"; imagehelp.SizeOfStruct = sizeof(imagehelp); framenum = 0; @@ -707,7 +712,7 @@ static callsite *calltree(int skip) frame[0].AddrStack.Mode = AddrModeFlat; frame[0].AddrFrame.Offset = context.Ebp; frame[0].AddrFrame.Mode = AddrModeFlat; - for (;;) { + for (;framenum < MAX_STACKFRAMES;) { PIMAGEHLP_SYMBOL symbol = (PIMAGEHLP_SYMBOL) buf; if (framenum) memcpy(&(frame[framenum]),&(frame[framenum-1]),sizeof(STACKFRAME)); @@ -731,7 +736,13 @@ static callsite *calltree(int skip) } if (frame[framenum].AddrPC.Offset == 0) break; + framenum++; + + /* + * Time to increase the number of stack frames? + */ + PR_ASSERT(framenum < MAX_STACKFRAMES); } depth = framenum; @@ -741,7 +752,7 @@ static callsite *calltree(int skip) /* Reverse the stack again, finding and building a path in the tree. */ parent = &calltree_root; - do { + while (0 < framenum) { DWORD displacement;/*used for getsymfromaddr*/ pc = frame[--framenum].AddrPC.Offset; @@ -795,21 +806,11 @@ static callsite *calltree(int skip) if (!SymGetModuleInfoEspecial(myProcess, frame[framenum].AddrPC.Offset, &imagehelp)) { - library = "unknown"; + library = noname; } else { library = imagehelp.ModuleName; } - symbol = (PIMAGEHLP_SYMBOL) buf; - symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL); - symbol->MaxNameLength = sizeof(buf) - sizeof(IMAGEHLP_SYMBOL); - symbol->Name[symbol->MaxNameLength] = '\0'; - - ok = _SymGetSymFromAddr(myProcess, - frame[framenum].AddrPC.Offset, - &displacement, - symbol); - /* Check whether we need to emit a library trace record. */ library_serial = 0; if (library) { @@ -857,12 +858,31 @@ static callsite *calltree(int skip) } } + symbol = (PIMAGEHLP_SYMBOL) buf; + symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL); + symbol->MaxNameLength = sizeof(buf) - sizeof(IMAGEHLP_SYMBOL); + symbol->Name[symbol->MaxNameLength] = '\0'; + + getSymRes = _SymGetSymFromAddr(myProcess, + frame[framenum].AddrPC.Offset, + &displacement, + symbol); + /* Now find the demangled method name and pc offset in it. */ - demangledname = (char *)malloc(MAX_UNMANGLED_NAME_LEN); - if (!_SymUnDName(symbol,demangledname,MAX_UNMANGLED_NAME_LEN)) - return 0; - method = demangledname; - offset = (char*)pc - (char*)(symbol->Address); + if (0 != getSymRes) { + demangledname = (char *)malloc(MAX_UNMANGLED_NAME_LEN); + if (!_SymUnDName(symbol,demangledname,MAX_UNMANGLED_NAME_LEN)) { + free(demangledname); + return 0; + } + method = demangledname; + offset = (char*)pc - (char*)(symbol->Address); + } + else { + method = noname; + offset = pc; + } + /* Emit an 'N' (for New method, 'M' is for malloc!) event if needed. */ method_serial = 0; if (!methods) { @@ -871,7 +891,9 @@ static callsite *calltree(int skip) &lfdset_hashallocops, NULL); if (!methods) { tmstats.btmalloc_failures++; - free((void*) method); + if (method != noname) { + free((void*) method); + } return NULL; } } @@ -880,7 +902,9 @@ static callsite *calltree(int skip) he = *hep; if (he) { method_serial = (uint32) he->value; - free((void*) method); + if (method != noname) { + free((void*) method); + } method = (char *) he->key; le = (lfdset_entry *) he; if (LFD_TEST(fp->lfd, &le->lfdset)) { @@ -893,7 +917,9 @@ static callsite *calltree(int skip) (void*) method_serial); if (!he) { tmstats.btmalloc_failures++; - free((void*) method); + if (method != noname) { + free((void*) method); + } return NULL; } le = (lfdset_entry *) he; @@ -943,7 +969,7 @@ static callsite *calltree(int skip) upward: parent = site; - } while (framenum); + } if (maxstack) calltree_maxstack_top = site; diff --git a/mozilla/xpcom/build/makefile.win b/mozilla/xpcom/build/makefile.win index d4db2e671fb..c3faed3ae13 100644 --- a/mozilla/xpcom/build/makefile.win +++ b/mozilla/xpcom/build/makefile.win @@ -94,7 +94,7 @@ WIN_LIBS = \ !ifdef GC_LEAK_DETECTOR $(DIST)\lib\boehm.lib \ !endif -!if defined(MOZ_DEBUG) +!if defined(MOZ_DEBUG) || defined(MOZ_TRACE_MALLOC) imagehlp.lib \ !endif $(NULL)