From 3137cde7b28e8924adc2237da8e6929a4b19d5a7 Mon Sep 17 00:00:00 2001 From: "timeless%mozdev.org" Date: Fri, 24 Jun 2005 05:20:27 +0000 Subject: [PATCH] backiing out git-svn-id: svn://10.0.0.236/trunk@175082 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/xpcom/base/nsStackFrameWin.cpp | 611 ++++++------------------- mozilla/xpcom/base/nsStackFrameWin.h | 54 +-- 2 files changed, 140 insertions(+), 525 deletions(-) diff --git a/mozilla/xpcom/base/nsStackFrameWin.cpp b/mozilla/xpcom/base/nsStackFrameWin.cpp index 84636c3d1e0..0c759ec185c 100644 --- a/mozilla/xpcom/base/nsStackFrameWin.cpp +++ b/mozilla/xpcom/base/nsStackFrameWin.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 @@ -40,6 +40,7 @@ #include "nscore.h" #include "windows.h" +#include "imagehlp.h" #include "stdio.h" #include "nsStackFrameWin.h" @@ -60,79 +61,36 @@ SYMINITIALIZEPROC _SymInitialize; SYMCLEANUPPROC _SymCleanup; STACKWALKPROC _StackWalk; -STACKWALKPROC64 _StackWalk64; SYMFUNCTIONTABLEACCESSPROC _SymFunctionTableAccess; -SYMFUNCTIONTABLEACCESSPROC64 _SymFunctionTableAccess64; SYMGETMODULEBASEPROC _SymGetModuleBase; -SYMGETMODULEBASEPROC64 _SymGetModuleBase64; -SYMFROMADDRPROC _SymFromAddr; +SYMGETSYMFROMADDRPROC _SymGetSymFromAddr; SYMLOADMODULE _SymLoadModule; -SYMLOADMODULE64 _SymLoadModule64; SYMUNDNAME _SymUnDName; SYMGETMODULEINFO _SymGetModuleInfo; -SYMGETMODULEINFO64 _SymGetModuleInfo64; ENUMLOADEDMODULES _EnumerateLoadedModules; -ENUMLOADEDMODULES64 _EnumerateLoadedModules64; SYMGETLINEFROMADDRPROC _SymGetLineFromAddr; -SYMGETLINEFROMADDRPROC64 _SymGetLineFromAddr64; - -HANDLE hStackWalkMutex; PR_END_EXTERN_C -// Routine to print an error message to standard error. -// Will also print to an additional stream if one is supplied. -void PrintError(char *prefix, FILE *out) -{ - LPVOID lpMsgBuf; - DWORD lastErr = GetLastError(); - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - lastErr, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR) &lpMsgBuf, - 0, - NULL - ); - fprintf(stderr, "### ERROR: %s: %s", prefix, lpMsgBuf); - if (out) - fprintf(out, "### ERROR: %s: %s\n", prefix, lpMsgBuf); - LocalFree( lpMsgBuf ); -} + + PRBool EnsureImageHlpInitialized() { - static PRBool gInitialized = PR_FALSE; + static PRBool gInitialized = PR_FALSE; - if (gInitialized) - return gInitialized; - - // Create a mutex with no initial owner. - hStackWalkMutex = CreateMutex( - NULL, // default security attributes - FALSE, // initially not owned - NULL); // unnamed mutex - - if (hStackWalkMutex == NULL) { - PrintError("CreateMutex", NULL); - return PR_FALSE; - } - - HMODULE module = ::LoadLibrary("DBGHELP.DLL"); - if (!module) { - module = ::LoadLibrary("IMAGEHLP.DLL"); - if (!module) return PR_FALSE; - } + if (! gInitialized) { + HMODULE module = ::LoadLibrary("IMAGEHLP.DLL"); + if (!module) return PR_FALSE; _SymSetOptions = (SYMSETOPTIONSPROC) ::GetProcAddress(module, "SymSetOptions"); if (!_SymSetOptions) return PR_FALSE; @@ -143,52 +101,46 @@ EnsureImageHlpInitialized() _SymCleanup = (SYMCLEANUPPROC)GetProcAddress(module, "SymCleanup"); if (!_SymCleanup) return PR_FALSE; - _StackWalk64 = (STACKWALKPROC64)GetProcAddress(module, "StackWalk64"); _StackWalk = (STACKWALKPROC)GetProcAddress(module, "StackWalk"); - if (!_StackWalk64 && !_StackWalk) return PR_FALSE; + if (!_StackWalk) return PR_FALSE; - _SymFunctionTableAccess64 = (SYMFUNCTIONTABLEACCESSPROC64) GetProcAddress(module, "SymFunctionTableAccess64"); _SymFunctionTableAccess = (SYMFUNCTIONTABLEACCESSPROC) GetProcAddress(module, "SymFunctionTableAccess"); - if (!_SymFunctionTableAccess64 && !_SymFunctionTableAccess) return PR_FALSE; + if (!_SymFunctionTableAccess) return PR_FALSE; - _SymGetModuleBase64 = (SYMGETMODULEBASEPROC64)GetProcAddress(module, "SymGetModuleBase64"); _SymGetModuleBase = (SYMGETMODULEBASEPROC)GetProcAddress(module, "SymGetModuleBase"); - if (!_SymGetModuleBase64 && !_SymGetModuleBase) return PR_FALSE; + if (!_SymGetModuleBase) return PR_FALSE; - _SymFromAddr = (SYMFROMADDRPROC)GetProcAddress(module, "SymFromAddr"); - if (!_SymFromAddr) return PR_FALSE; + _SymGetSymFromAddr = (SYMGETSYMFROMADDRPROC)GetProcAddress(module, "SymGetSymFromAddr"); + if (!_SymGetSymFromAddr) return PR_FALSE; - _SymLoadModule64 = (SYMLOADMODULE64)GetProcAddress(module, "SymLoadModule64"); _SymLoadModule = (SYMLOADMODULE)GetProcAddress(module, "SymLoadModule"); - if (!_SymLoadModule64 && !_SymLoadModule) return PR_FALSE; + if (!_SymLoadModule) return PR_FALSE; _SymUnDName = (SYMUNDNAME)GetProcAddress(module, "SymUnDName"); if (!_SymUnDName) return PR_FALSE; - _SymGetModuleInfo64 = (SYMGETMODULEINFO64)GetProcAddress(module, "SymGetModuleInfo64"); _SymGetModuleInfo = (SYMGETMODULEINFO)GetProcAddress(module, "SymGetModuleInfo"); - if (!_SymGetModuleInfo64 && !_SymGetModuleInfo) return PR_FALSE; + if (!_SymGetModuleInfo) return PR_FALSE; - _EnumerateLoadedModules64 = (ENUMLOADEDMODULES64)GetProcAddress(module, "EnumerateLoadedModules64"); _EnumerateLoadedModules = (ENUMLOADEDMODULES)GetProcAddress(module, "EnumerateLoadedModules"); - if (!_EnumerateLoadedModules64 && !_EnumerateLoadedModules) return PR_FALSE; + if (!_EnumerateLoadedModules) return PR_FALSE; - _SymGetLineFromAddr64 = (SYMGETLINEFROMADDRPROC64)GetProcAddress(module, "SymGetLineFromAddr64"); _SymGetLineFromAddr = (SYMGETLINEFROMADDRPROC)GetProcAddress(module, "SymGetLineFromAddr"); - if (!_SymGetLineFromAddr64 && !_SymGetLineFromAddr) return PR_FALSE; + if (!_SymGetLineFromAddr) return PR_FALSE; - return gInitialized = PR_TRUE; -} + gInitialized = PR_TRUE; + } + return gInitialized; +} -static BOOL CALLBACK callbackEspecial( - LPSTR aModuleName, - DWORD aModuleBase, - ULONG aModuleSize, - PVOID aUserContext) +/* + * Callback used by SymGetModuleInfoEspecial + */ +static BOOL CALLBACK callbackEspecial(LPSTR aModuleName, ULONG aModuleBase, ULONG aModuleSize, PVOID aUserContext) { BOOL retval = TRUE; - DWORD addr = *(DWORD*)aUserContext; + DWORD addr = (DWORD)aUserContext; /* * You'll want to control this if we are running on an @@ -196,44 +148,20 @@ static BOOL CALLBACK callbackEspecial( * Not sure this is even a realistic consideration. */ const BOOL addressIncreases = TRUE; - - /* - * If it falls inside the known range, load the symbols. - */ - if (addressIncreases - ? (addr >= aModuleBase && addr <= (aModuleBase + aModuleSize)) - : (addr <= aModuleBase && addr >= (aModuleBase - aModuleSize)) - ) { - retval = _SymLoadModule(GetCurrentProcess(), NULL, aModuleName, NULL, aModuleBase, aModuleSize); - } - - return retval; -} - -static BOOL CALLBACK callbackEspecial64( - PTSTR aModuleName, - DWORD64 aModuleBase, - ULONG aModuleSize, - PVOID aUserContext) -{ - BOOL retval = TRUE; - DWORD64 addr = *(DWORD64*)aUserContext; - - /* - * You'll want to control this if we are running on an - * architecture where the addresses go the other direction. - * Not sure this is even a realistic consideration. - */ - const BOOL addressIncreases = TRUE; - + /* * If it falls in side the known range, load the symbols. */ - if (addressIncreases + if(addressIncreases ? (addr >= aModuleBase && addr <= (aModuleBase + aModuleSize)) : (addr <= aModuleBase && addr >= (aModuleBase - aModuleSize)) - ) { - retval = _SymLoadModule64(GetCurrentProcess(), NULL, aModuleName, NULL, aModuleBase, aModuleSize); + ) + { + BOOL loadRes = FALSE; + HANDLE process = GetCurrentProcess(); + + loadRes = _SymLoadModule(process, NULL, aModuleName, NULL, aModuleBase, aModuleSize); + PR_ASSERT(FALSE != loadRes); } return retval; @@ -273,8 +201,8 @@ BOOL SymGetModuleInfoEspecial(HANDLE aProcess, DWORD aAddr, PIMAGEHLP_MODULE aMo * Not loaded, here's the magic. * Go through all the modules. */ - enumRes = _EnumerateLoadedModules(aProcess, callbackEspecial, (PVOID)&aAddr); - if (FALSE != enumRes) + enumRes = _EnumerateLoadedModules(aProcess, callbackEspecial, (PVOID)aAddr); + if(FALSE != enumRes) { /* * One final go. @@ -289,396 +217,131 @@ BOOL SymGetModuleInfoEspecial(HANDLE aProcess, DWORD aAddr, PIMAGEHLP_MODULE aMo * We will not report failure if this does not work. */ if (FALSE != retval && nsnull != aLineInfo && nsnull != _SymGetLineFromAddr) { - DWORD displacement = 0; - BOOL lineRes = FALSE; - lineRes = _SymGetLineFromAddr(aProcess, aAddr, &displacement, aLineInfo); + DWORD displacement = 0; + BOOL lineRes = FALSE; + + lineRes = _SymGetLineFromAddr(aProcess, aAddr, &displacement, aLineInfo); } return retval; } -BOOL SymGetModuleInfoEspecial64(HANDLE aProcess, DWORD64 aAddr, PIMAGEHLP_MODULE64 aModuleInfo, PIMAGEHLP_LINE64 aLineInfo) -{ - BOOL retval = FALSE; - - /* - * Init the vars if we have em. - */ - aModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE64); - if (nsnull != aLineInfo) { - aLineInfo->SizeOfStruct = sizeof(IMAGEHLP_LINE64); - } - - /* - * Give it a go. - * It may already be loaded. - */ - retval = _SymGetModuleInfo64(aProcess, aAddr, aModuleInfo); - - if (FALSE == retval) { - BOOL enumRes = FALSE; - - /* - * Not loaded, here's the magic. - * Go through all the modules. - */ - enumRes = _EnumerateLoadedModules64(aProcess, callbackEspecial64, (PVOID)&aAddr); - if (FALSE != enumRes) - { - /* - * One final go. - * If it fails, then well, we have other problems. - */ - retval = _SymGetModuleInfo64(aProcess, aAddr, aModuleInfo); - } - } - - /* - * If we got module info, we may attempt line info as well. - * We will not report failure if this does not work. - */ - if (FALSE != retval && nsnull != aLineInfo && nsnull != _SymGetLineFromAddr64) { - DWORD displacement = 0; - BOOL lineRes = FALSE; - lineRes = _SymGetLineFromAddr64(aProcess, aAddr, &displacement, aLineInfo); - } - - return retval; -} - -HANDLE -GetCurrentPIDorHandle() -{ - if (_SymGetModuleBase64) - return GetCurrentProcess(); // winxp and friends use process handle - - return (HANDLE) GetCurrentProcessId(); // winme win98 win95 etc use process identifier -} - PRBool EnsureSymInitialized() -{ - PRBool retStat; - - if (!EnsureImageHlpInitialized()) - return PR_FALSE; +{ + static PRBool gInitialized = PR_FALSE; + if (! gInitialized) { + if (! EnsureImageHlpInitialized()) + return PR_FALSE; _SymSetOptions(SYMOPT_LOAD_LINES | SYMOPT_UNDNAME); - retStat = _SymInitialize(GetCurrentPIDorHandle(), NULL, TRUE); - if (!retStat) - PrintError("SymInitialize", NULL); - return retStat; + gInitialized = _SymInitialize(GetCurrentProcess(), 0, TRUE); + } + return gInitialized; } /** * Walk the stack, translating PC's found into strings and recording the - * chain in aBuffer. For this to work properly, the DLLs must be rebased + * chain in aBuffer. For this to work properly, the dll's must be rebased * so that the address in the file agrees with the address in memory. - * Otherwise StackWalk will return FALSE when it hits a frame in a DLLs + * Otherwise StackWalk will return FALSE when it hits a frame in a dll's * whose in memory address doesn't match it's in-file address. */ + void -DumpStackToFile(FILE* aStream) +DumpStackToFile(FILE* aStream) { - HANDLE myProcess = ::GetCurrentProcess(); - HANDLE myThread, walkerThread; - DWORD walkerReturn; - struct DumpStackToFileData data; + HANDLE myProcess = ::GetCurrentProcess(); + HANDLE myThread = ::GetCurrentThread(); + BOOL ok; - if (!EnsureSymInitialized()) - return; - - // Have to duplicate handle to get a real handle. - ::DuplicateHandle( - ::GetCurrentProcess(), - ::GetCurrentThread(), - ::GetCurrentProcess(), - &myThread, - THREAD_ALL_ACCESS, FALSE, 0 - ); - - data.stream = aStream; - data.thread = myThread; - data.process = myProcess; - walkerThread = ::CreateThread( NULL, 0, DumpStackToFileThread, (LPVOID) &data, 0, NULL ) ; - walkerReturn = ::WaitForSingleObject(walkerThread, INFINITE); - CloseHandle(myThread) ; - if (walkerReturn != WAIT_OBJECT_0) - PrintError("ThreadWait", aStream); + ok = EnsureSymInitialized(); + if (! ok) return; -} -DWORD WINAPI -DumpStackToFileThread(LPVOID lpdata) -{ - struct DumpStackToFileData *data = (DumpStackToFileData *)lpdata; - DWORD ret ; + // Get the context information for this thread. That way we will + // know where our sp, fp, pc, etc. are and can fill in the + // STACKFRAME with the initial values. + CONTEXT context; + context.ContextFlags = CONTEXT_FULL; + ok = GetThreadContext(myThread, &context); + if (! ok) + return; - // Suspend the calling thread, dump his stack, and then resume him. - // He's currently waiting for us to finish so now should be a good time. - ret = ::SuspendThread( data->thread ); - if (ret == -1) { - PrintError("ThreadSuspend", data->stream); + // Setup initial stack frame to walk from + STACKFRAME frame; + memset(&frame, 0, sizeof(frame)); + frame.AddrPC.Offset = context.Eip; + frame.AddrPC.Mode = AddrModeFlat; + frame.AddrStack.Offset = context.Esp; + frame.AddrStack.Mode = AddrModeFlat; + frame.AddrFrame.Offset = context.Ebp; + frame.AddrFrame.Mode = AddrModeFlat; + + // Now walk the stack and map the pc's to symbol names + int skip = 2; + while (1) { + ok = _StackWalk(IMAGE_FILE_MACHINE_I386, + myProcess, + myThread, + &frame, + &context, + 0, // read process memory routine + _SymFunctionTableAccess, // function table access routine + _SymGetModuleBase, // module base routine + 0); // translate address routine + + if (!ok) { + LPVOID lpMsgBuf; + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL + ); + fprintf(aStream, "### ERROR: WalkStack: %s", lpMsgBuf); + fflush(aStream); + LocalFree( lpMsgBuf ); + } + if (!ok || frame.AddrPC.Offset == 0) + break; + + if (skip-- > 0) + continue; + + // + // Attempt to load module info before we attempt to reolve the symbol. + // This just makes sure we get good info if available. + // + IMAGEHLP_MODULE modInfo; + modInfo.SizeOfStruct = sizeof(modInfo); + BOOL modInfoRes = TRUE; + modInfoRes = SymGetModuleInfoEspecial(myProcess, frame.AddrPC.Offset, &modInfo, nsnull); + + char buf[sizeof(IMAGEHLP_SYMBOL) + 512]; + PIMAGEHLP_SYMBOL symbol = (PIMAGEHLP_SYMBOL) buf; + symbol->SizeOfStruct = sizeof(buf); + symbol->MaxNameLength = 512; + + DWORD displacement; + ok = _SymGetSymFromAddr(myProcess, + frame.AddrPC.Offset, + &displacement, + symbol); + + if (ok) { + fprintf(aStream, "%s+0x%08X\n", symbol->Name, displacement); } else { - if (_StackWalk64) - DumpStackToFileMain64(data); - else - DumpStackToFileMain(data); - ret = ::ResumeThread( data->thread ); - if (ret == -1) { - PrintError("ThreadResume", data->stream); - } + fprintf(aStream, "0x%08X\n", frame.AddrPC.Offset); } - - return 0; -} - -void -DumpStackToFileMain64(struct DumpStackToFileData* data) -{ - // Get the context information for the thread. That way we will - // know where our sp, fp, pc, etc. are and can fill in the - // STACKFRAME64 with the initial values. - CONTEXT context; - HANDLE myProcess = data->process; - HANDLE myThread = data->thread; - FILE* aStream = data->stream; - DWORD64 addr; - STACKFRAME64 frame64; - int skip = 6; // skip our own stack walking frames - BOOL ok; - - // Get a context for the specified thread. - memset(&context, 0, sizeof(CONTEXT)); - context.ContextFlags = CONTEXT_FULL; - if (!GetThreadContext(myThread, &context)) { - PrintError("GetThreadContext", aStream); - return; - } - - // Setup initial stack frame to walk from - memset(&frame64, 0, sizeof(frame64)); -#ifdef _M_IX86 - frame64.AddrPC.Offset = context.Eip; - frame64.AddrStack.Offset = context.Esp; - frame64.AddrFrame.Offset = context.Ebp; -#elif defined _M_AMD64 - frame64.AddrPC.Offset = context.Rip; - frame64.AddrStack.Offset = context.Rsp; - frame64.AddrFrame.Offset = context.Rbp; -#elif defined _M_IA64 - frame64.AddrPC.Offset = context.StIIP; - frame64.AddrStack.Offset = context.SP; - frame64.AddrFrame.Offset = context.RsBSP; -#else - fprintf(aStream, "Unknown platform. No stack walking."); - return; -#endif - frame64.AddrPC.Mode = AddrModeFlat; - frame64.AddrStack.Mode = AddrModeFlat; - frame64.AddrFrame.Mode = AddrModeFlat; - frame64.AddrReturn.Mode = AddrModeFlat; - - // Now walk the stack and map the pc's to symbol names - while (1) { - - ok = 0; - - // stackwalk is not threadsafe, so grab the lock. - DWORD dwWaitResult; - dwWaitResult = WaitForSingleObject(hStackWalkMutex, INFINITE); - if (dwWaitResult == WAIT_OBJECT_0) { - - ok = _StackWalk64( -#ifdef _M_AMD64 - IMAGE_FILE_MACHINE_AMD64, -#elif defined _M_IA64 - IMAGE_FILE_MACHINE_IA64, -#elif defined _M_IX86 - IMAGE_FILE_MACHINE_I386, -#else - 0, -#endif - myProcess, - myThread, - &frame64, - &context, - NULL, - _SymFunctionTableAccess64, // function table access routine - _SymGetModuleBase64, // module base routine - 0 - ); - - if (ok) - addr = frame64.AddrPC.Offset; - else - PrintError("WalkStack64", aStream); - - if (!ok || (addr == 0)) { - ReleaseMutex(hStackWalkMutex); // release our lock - break; - } - - if (skip-- > 0) { - ReleaseMutex(hStackWalkMutex); // release our lock - continue; - } - - // - // Attempt to load module info before we attempt to reolve the symbol. - // This just makes sure we get good info if available. - // - - IMAGEHLP_MODULE64 modInfo; - modInfo.SizeOfStruct = sizeof(modInfo); - BOOL modInfoRes; - modInfoRes = SymGetModuleInfoEspecial64(myProcess, addr, &modInfo, nsnull); - - ULONG64 buffer[(sizeof(SYMBOL_INFO) + - MAX_SYM_NAME*sizeof(TCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64)]; - PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer; - pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); - pSymbol->MaxNameLen = MAX_SYM_NAME; - - DWORD64 displacement; - ok = _SymFromAddr(myProcess, addr, &displacement, pSymbol); - - // All done with debug calls so release our lock. - ReleaseMutex(hStackWalkMutex); - - if (ok) - fprintf(aStream, "%s!%s+0x%016X\n", modInfo.ImageName, pSymbol->Name, displacement); - else - fprintf(aStream, "0x%016X\n", addr); - - // Stop walking when we get to kernel32.dll. - if (strcmp(modInfo.ImageName,"kernel32.dll") == 0) - break; - } - else { - PrintError("LockError64", aStream); - } - } - return; -} - - -void -DumpStackToFileMain(struct DumpStackToFileData* data) -{ - // Get the context information for the thread. That way we will - // know where our sp, fp, pc, etc. are and can fill in the - // STACKFRAME with the initial values. - CONTEXT context; - HANDLE myProcess = data->process; - HANDLE myThread = data->thread; - FILE* aStream = data->stream; - DWORD addr; - STACKFRAME frame; - int skip = 2; // skip our own stack walking frames - BOOL ok; - - // Get a context for the specified thread. - memset(&context, 0, sizeof(CONTEXT)); - context.ContextFlags = CONTEXT_FULL; - if (!GetThreadContext(myThread, &context)) { - PrintError("GetThreadContext", aStream); - return; - } - - // Setup initial stack frame to walk from -#if defined _M_IX86 - memset(&frame, 0, sizeof(frame)); - frame.AddrPC.Offset = context.Eip; - frame.AddrPC.Mode = AddrModeFlat; - frame.AddrStack.Offset = context.Esp; - frame.AddrStack.Mode = AddrModeFlat; - frame.AddrFrame.Offset = context.Ebp; - frame.AddrFrame.Mode = AddrModeFlat; -#else - fprintf(aStream, "Unknown platform. No stack walking."); - return; -#endif - - // Now walk the stack and map the pc's to symbol names - while (1) { - - ok = 0; - - // debug routines are not threadsafe, so grab the lock. - DWORD dwWaitResult; - dwWaitResult = WaitForSingleObject(hStackWalkMutex, INFINITE); - if (dwWaitResult == WAIT_OBJECT_0) { - - ok = _StackWalk( - IMAGE_FILE_MACHINE_I386, - myProcess, - myThread, - &frame, - &context, - 0, // read process memory routine - _SymFunctionTableAccess, // function table access routine - _SymGetModuleBase, // module base routine - 0 // translate address routine - ); - - if (ok) - addr = frame.AddrPC.Offset; - else - PrintError("WalkStack", aStream); - - if (!ok || (addr == 0)) { - ReleaseMutex(hStackWalkMutex); // release our lock - break; - } - - if (skip-- > 0) { - ReleaseMutex(hStackWalkMutex); // release the lock - continue; - } - - // - // Attempt to load module info before we attempt to resolve the symbol. - // This just makes sure we get good info if available. - // - - IMAGEHLP_MODULE modInfo; - modInfo.SizeOfStruct = sizeof(modInfo); - BOOL modInfoRes; - modInfoRes = SymGetModuleInfoEspecial(myProcess, addr, &modInfo, nsnull); - - ULONG64 buffer[(sizeof(SYMBOL_INFO) + - MAX_SYM_NAME*sizeof(TCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64)]; - PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer; - pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); - pSymbol->MaxNameLen = MAX_SYM_NAME; - - DWORD64 displacement; - ok = _SymFromAddr(myProcess, addr, &displacement, pSymbol); - - // All done with debug calls so release our lock. - ReleaseMutex(hStackWalkMutex); - - if (ok) - fprintf(aStream, "%s!%s+0x%08X\n", modInfo.ImageName, pSymbol->Name, displacement); - else - fprintf(aStream, "0x%08X\n", (DWORD) addr); - - // Stop walking when we get to kernel32.dll. - if (strcmp(modInfo.ImageName,"kernel32.dll") == 0) - break; - - } - else { - PrintError("LockError", aStream); - } - - } - - return; - + } } diff --git a/mozilla/xpcom/base/nsStackFrameWin.h b/mozilla/xpcom/base/nsStackFrameWin.h index d7f5da9f7b3..d9b6585c64b 100644 --- a/mozilla/xpcom/base/nsStackFrameWin.h +++ b/mozilla/xpcom/base/nsStackFrameWin.h @@ -41,13 +41,10 @@ #define nsStackFrameWin_h___ -#if defined(_WIN32) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_IA64)) -// WIN32 x86 stack walking code +#if defined(_WIN32) && defined(_M_IX86) // WIN32 x86 stack walking code #include "nspr.h" #include -#ifdef _M_IX86 #include -#endif // Define these as static pointers so that we can load the DLL on the // fly (and not introduce a link-time dependency on it). Tip o' the @@ -77,63 +74,30 @@ typedef BOOL (__stdcall *STACKWALKPROC)(DWORD, PTRANSLATE_ADDRESS_ROUTINE); extern STACKWALKPROC _StackWalk; -typedef BOOL (__stdcall *STACKWALKPROC64)(DWORD, - HANDLE, - HANDLE, - LPSTACKFRAME64, - PVOID, - PREAD_PROCESS_MEMORY_ROUTINE64, - PFUNCTION_TABLE_ACCESS_ROUTINE64, - PGET_MODULE_BASE_ROUTINE64, - PTRANSLATE_ADDRESS_ROUTINE64); -extern STACKWALKPROC64 _StackWalk64; - typedef LPVOID (__stdcall *SYMFUNCTIONTABLEACCESSPROC)(HANDLE, DWORD); extern SYMFUNCTIONTABLEACCESSPROC _SymFunctionTableAccess; -typedef LPVOID (__stdcall *SYMFUNCTIONTABLEACCESSPROC64)(HANDLE, DWORD64); -extern SYMFUNCTIONTABLEACCESSPROC64 _SymFunctionTableAccess64; - typedef DWORD (__stdcall *SYMGETMODULEBASEPROC)(HANDLE, DWORD); extern SYMGETMODULEBASEPROC _SymGetModuleBase; -typedef DWORD64 (__stdcall *SYMGETMODULEBASEPROC64)(HANDLE, DWORD64); -extern SYMGETMODULEBASEPROC64 _SymGetModuleBase64; - -typedef BOOL (__stdcall *SYMFROMADDRPROC)(HANDLE, DWORD64, PDWORD64, PSYMBOL_INFO); -extern SYMFROMADDRPROC _SymFromAddr; +typedef BOOL (__stdcall *SYMGETSYMFROMADDRPROC)(HANDLE, DWORD, PDWORD, PIMAGEHLP_SYMBOL); +extern SYMGETSYMFROMADDRPROC _SymGetSymFromAddr; typedef DWORD ( __stdcall *SYMLOADMODULE)(HANDLE, HANDLE, PSTR, PSTR, DWORD, DWORD); extern SYMLOADMODULE _SymLoadModule; -typedef DWORD ( __stdcall *SYMLOADMODULE64)(HANDLE, HANDLE, PCSTR, PCSTR, DWORD64, DWORD); -extern SYMLOADMODULE64 _SymLoadModule64; - typedef DWORD ( __stdcall *SYMUNDNAME)(PIMAGEHLP_SYMBOL, PSTR, DWORD); extern SYMUNDNAME _SymUnDName; typedef DWORD ( __stdcall *SYMGETMODULEINFO)( HANDLE, DWORD, PIMAGEHLP_MODULE); extern SYMGETMODULEINFO _SymGetModuleInfo; -typedef BOOL ( __stdcall *SYMGETMODULEINFO64)( HANDLE, DWORD64, PIMAGEHLP_MODULE64); -extern SYMGETMODULEINFO64 _SymGetModuleInfo64; - typedef BOOL ( __stdcall *ENUMLOADEDMODULES)( HANDLE, PENUMLOADED_MODULES_CALLBACK, PVOID); extern ENUMLOADEDMODULES _EnumerateLoadedModules; -typedef BOOL ( __stdcall *ENUMLOADEDMODULES64)( HANDLE, PENUMLOADED_MODULES_CALLBACK64, PVOID); -extern ENUMLOADEDMODULES64 _EnumerateLoadedModules64; - typedef BOOL (__stdcall *SYMGETLINEFROMADDRPROC)(HANDLE, DWORD, PDWORD, PIMAGEHLP_LINE); extern SYMGETLINEFROMADDRPROC _SymGetLineFromAddr; -typedef BOOL (__stdcall *SYMGETLINEFROMADDRPROC64)(HANDLE, DWORD64, PDWORD, PIMAGEHLP_LINE64); -extern SYMGETLINEFROMADDRPROC64 _SymGetLineFromAddr64; - -extern HANDLE hStackWalkMutex; - -HANDLE GetCurrentPIDorHandle(); - PRBool EnsureSymInitialized(); PRBool EnsureImageHlpInitialized(); @@ -150,23 +114,11 @@ PRBool EnsureImageHlpInitialized(); */ BOOL SymGetModuleInfoEspecial(HANDLE aProcess, DWORD aAddr, PIMAGEHLP_MODULE aModuleInfo, PIMAGEHLP_LINE aLineInfo); -struct DumpStackToFileData { - FILE *stream; - HANDLE thread; - HANDLE process; -}; -void PrintError(char *prefix, FILE* out); void DumpStackToFile(FILE* out); -DWORD WINAPI DumpStackToFileThread(LPVOID data); -void DumpStackToFileMain64(struct DumpStackToFileData* data); -void DumpStackToFileMain(struct DumpStackToFileData* data); - PR_END_EXTERN_C -#else -#pragma message( "You probably need to fix this file to handle your target platform" ) #endif //WIN32 #endif //nsStackFrameWin_h___