move nsTraceMalloc out of XPCOM. Factory out stackwalking code into new files. 189221 r=chak, 186585 r=blythe sr=dbaron. Most of this patch was contributed by seawood.

git-svn-id: svn://10.0.0.236/trunk@136371 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
dougt%netscape.com
2003-01-15 20:40:06 +00:00
parent 5288b89c2a
commit a2a82fab36
29 changed files with 1423 additions and 1371 deletions

View File

@@ -36,7 +36,6 @@
*
* ***** END LICENSE BLOCK ***** */
/* Win32 x86 code for stack walking, symbol resolution, and function hooking */
#if defined(_WIN32) && defined(_M_IX86)
// This is the .cpp file where the globals live
@@ -48,19 +47,23 @@
#include "plstr.h"
#include "prlock.h"
#include "nscore.h"
#include "nsAutoLock.h"
#include "nsDebugHelpWin32.h"
#include "nsStackFrameWin.h"
#else
#error "nsDebugHelpWin32.cpp should only be built in Win32 x86 builds"
#endif
/***************************************************************************/
PRLock* DHWImportHooker::gLock = nsnull;
DHWImportHooker* DHWImportHooker::gHooks = nsnull;
GETPROCADDRESS DHWImportHooker::gRealGetProcAddress = nsnull;
PRBool
static PRBool
dhwEnsureImageHlpInitialized()
{
static PRBool gInitialized = PR_FALSE;
@@ -82,24 +85,9 @@ dhwEnsureImageHlpInitialized()
dhw##name_ = (typename_) ::GetProcAddress(module, #name_); \
if(!dhw##name_) return PR_FALSE;
INIT_PROC(SYMINITIALIZEPROC, SymInitialize);
INIT_PROC(SYMSETOPTIONS, SymSetOptions);
INIT_PROC(SYMGETOPTIONS, SymGetOptions);
INIT_PROC(SYMGETMODULEINFO, SymGetModuleInfo);
INIT_PROC(SYMGETSYMFROMADDRPROC, SymGetSymFromAddr);
INIT_PROC(ENUMERATELOADEDMODULES, EnumerateLoadedModules);
INIT_PROC(IMAGEDIRECTORYENTRYTODATA, ImageDirectoryEntryToData);
// INIT_PROC(SYMGETLINEFROMADDR, SymGetLineFromAddr);
// INIT_PROC(SYMCLEANUPPROC, SymCleanup);
// INIT_PROC(STACKWALKPROC, StackWalk);
// INIT_PROC(SYMFUNCTIONTABLEACCESSPROC, SymFunctionTableAccess);
// INIT_PROC(SYMGETMODULEBASEPROC, SymGetModuleBase);
// INIT_PROC(SYMLOADMODULE, SymLoadModule);
// INIT_PROC(UNDECORATESYMBOLNAME, UnDecorateSymbolName);
// INIT_PROC(SYMUNDNAME, SymUnDName);
#undef INIT_PROC
gInitialized = PR_TRUE;
@@ -108,33 +96,6 @@ dhwEnsureImageHlpInitialized()
return gInitialized;
}
PRBool
dhwEnsureSymInitialized()
{
static PRBool gInitialized = PR_FALSE;
if (! gInitialized) {
if (! dhwEnsureImageHlpInitialized())
return PR_FALSE;
dhwSymSetOptions(
#if defined(NS_TRACE_MALLOC)
SYMOPT_LOAD_LINES |
#endif
SYMOPT_UNDNAME);
// dhwSymSetOptions(SYMOPT_UNDNAME);
if (! dhwSymInitialize(::GetCurrentProcess(), NULL, TRUE))
return PR_FALSE;
gInitialized = PR_TRUE;
}
return gInitialized;
}
/***************************************************************************/
PRLock* DHWImportHooker::gLock = nsnull;
DHWImportHooker* DHWImportHooker::gHooks = nsnull;
GETPROCADDRESS DHWImportHooker::gRealGetProcAddress = nsnull;
DHWImportHooker&
DHWImportHooker::getGetProcAddressHooker()
@@ -201,9 +162,10 @@ DHWImportHooker::DHWImportHooker(const char* aModuleName,
if(!gLock)
gLock = PR_NewLock();
nsAutoLock lock(gLock);
PR_Lock(gLock);
dhwEnsureImageHlpInitialized();
EnsureImageHlpInitialized();
dhwEnsureImageHlpInitialized(); // for the extra ones we care about.
if(!gRealGetProcAddress)
gRealGetProcAddress = ::GetProcAddress;
@@ -215,11 +177,13 @@ DHWImportHooker::DHWImportHooker(const char* aModuleName,
gHooks = this;
PatchAllModules();
PR_Unlock(gLock);
}
DHWImportHooker::~DHWImportHooker()
{
nsAutoLock lock(gLock);
PR_Lock(gLock);
mHooking = PR_FALSE;
PatchAllModules();
@@ -236,16 +200,18 @@ DHWImportHooker::~DHWImportHooker()
break;
}
}
NS_ASSERTION(cur, "we were not in the list!");
PR_ASSERT(cur); //we were not in the list!
}
if(!gHooks)
{
PRLock* theLock = gLock;
gLock = nsnull;
lock.unlock();
PR_Unlock(theLock);
PR_DestroyLock(theLock);
}
if (gLock)
PR_Unlock(gLock);
}
static BOOL CALLBACK ModuleEnumCallback(LPSTR ModuleName,
@@ -351,11 +317,12 @@ DHWImportHooker::ModuleLoaded(HMODULE aModule, DWORD flags)
//printf("ModuleLoaded\n");
if(aModule && !(flags & LOAD_LIBRARY_AS_DATAFILE))
{
nsAutoLock lock(gLock);
PR_Lock(gLock);
// We don't know that the newly loaded module didn't drag in implicitly
// linked modules, so we patch everything in sight.
for(DHWImportHooker* cur = gHooks; cur; cur = cur->mNext)
cur->PatchAllModules();
PR_Unlock(gLock);
}
return PR_TRUE;
}
@@ -413,7 +380,7 @@ DHWImportHooker::GetProcAddress(HMODULE aModule, PCSTR aFunctionName)
if(pfn)
{
nsAutoLock lock(gLock);
PR_Lock(gLock);
for(DHWImportHooker* cur = gHooks; cur; cur = cur->mNext)
{
if(pfn == cur->mOriginal)
@@ -422,75 +389,9 @@ DHWImportHooker::GetProcAddress(HMODULE aModule, PCSTR aFunctionName)
break;
}
}
PR_Unlock(gLock);
}
return pfn;
}
/***************************************************************************/
#if 0
static _CRT_ALLOC_HOOK defaultDbgAllocHook = nsnull;
static DHWAllocationSizeDebugHook* gAllocationSizeHook = nsnull;
int __cdecl dhw_DbgAllocHook(int nAllocType, void *pvData,
size_t nSize, int nBlockUse, long lRequest,
const unsigned char * szFileName, int nLine )
{
DHWAllocationSizeDebugHook* hook = gAllocationSizeHook;
if(hook)
{
PRBool res;
_CrtSetAllocHook(defaultDbgAllocHook);
switch(nAllocType)
{
case _HOOK_ALLOC:
res = hook->AllocHook(nSize);
break;
case _HOOK_REALLOC:
res = hook->ReallocHook(nSize, pvData ?
_msize_dbg(pvData, nBlockUse) : 0);
break;
case _HOOK_FREE:
res = hook->FreeHook(pvData ?
_msize_dbg(pvData, nBlockUse) : 0);
break;
default:
NS_ASSERTION(0,"huh?");
res = PR_TRUE;
break;
}
_CrtSetAllocHook(dhw_DbgAllocHook);
return (int) res;
}
return 1;
}
PRBool
dhwSetAllocationSizeDebugHook(DHWAllocationSizeDebugHook* hook)
{
if(!hook || gAllocationSizeHook)
return PR_FALSE;
gAllocationSizeHook = hook;
if(!defaultDbgAllocHook)
defaultDbgAllocHook = _CrtSetAllocHook(dhw_DbgAllocHook);
else
_CrtSetAllocHook(dhw_DbgAllocHook);
return PR_TRUE;
}
PRBool
dhwClearAllocationSizeDebugHook()
{
if(!gAllocationSizeHook)
return PR_FALSE;
gAllocationSizeHook = nsnull;
_CrtSetAllocHook(defaultDbgAllocHook);
return PR_TRUE;
}
#endif //0