diff options
author | ivmai <ivmai> | 2011-03-13 19:53:03 +0000 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2011-07-26 21:06:56 +0400 |
commit | 015db4806b7299592a94e3099b0fe50cca2b1e58 (patch) | |
tree | 6f1afe15759e6b993b2802ceea8fd8a49e66ee49 /extra/msvc_dbg.c | |
parent | 618a4c49d9c8c50e95f075e11e826aded68518cd (diff) | |
download | bdwgc-015db4806b7299592a94e3099b0fe50cca2b1e58.tar.gz |
2011-03-13 Ivan Maidanski <ivmai@mail.ru>
* extra/msvc_dbg.c: Test _MSC_VER macro; include "gc.h" (for
GC_word); reformat the code; expand all tabs to spaces.
* extra/msvc_dbg.c (ULONG_PTR): Replace with GC_ULONG_PTR; define
as word.
Diffstat (limited to 'extra/msvc_dbg.c')
-rw-r--r-- | extra/msvc_dbg.c | 504 |
1 files changed, 266 insertions, 238 deletions
diff --git a/extra/msvc_dbg.c b/extra/msvc_dbg.c index 2420a44b..5bc216a1 100644 --- a/extra/msvc_dbg.c +++ b/extra/msvc_dbg.c @@ -19,12 +19,15 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef _M_AMD64 -/* X86_64 is ccurrently missing some meachine-dependent code below. */ +#if !defined(_M_AMD64) && defined(_MSC_VER) + +/* X86_64 is currently missing some meachine-dependent code below. */ #include "private/msvc_dbg.h" +#include "gc.h" + #define WIN32_LEAN_AND_MEAN #include <windows.h> @@ -35,319 +38,344 @@ #pragma comment(lib, "dbghelp.lib") #pragma optimize("gy", off) +typedef GC_word word; +#define GC_ULONG_PTR word + #ifdef _WIN64 - typedef ULONG_PTR ULONG_ADDR; + typedef GC_ULONG_PTR ULONG_ADDR; #else - typedef ULONG ULONG_ADDR; + typedef ULONG ULONG_ADDR; #endif static HANDLE GetSymHandle() { - static HANDLE symHandle = NULL; - if (!symHandle) { - BOOL bRet = SymInitialize(symHandle = GetCurrentProcess(), NULL, FALSE); - if (bRet) { - DWORD dwOptions = SymGetOptions(); - dwOptions &= ~SYMOPT_UNDNAME; - dwOptions |= SYMOPT_LOAD_LINES; - SymSetOptions(dwOptions); - } - } - return symHandle; + static HANDLE symHandle = NULL; + if (!symHandle) { + BOOL bRet = SymInitialize(symHandle = GetCurrentProcess(), NULL, FALSE); + if (bRet) { + DWORD dwOptions = SymGetOptions(); + dwOptions &= ~SYMOPT_UNDNAME; + dwOptions |= SYMOPT_LOAD_LINES; + SymSetOptions(dwOptions); + } + } + return symHandle; } -static void* CALLBACK FunctionTableAccess(HANDLE hProcess, ULONG_ADDR dwAddrBase) +static void* CALLBACK FunctionTableAccess(HANDLE hProcess, + ULONG_ADDR dwAddrBase) { - return SymFunctionTableAccess(hProcess, dwAddrBase); + return SymFunctionTableAccess(hProcess, dwAddrBase); } static ULONG_ADDR CALLBACK GetModuleBase(HANDLE hProcess, ULONG_ADDR dwAddress) { - MEMORY_BASIC_INFORMATION memoryInfo; - ULONG_ADDR dwAddrBase = SymGetModuleBase(hProcess, dwAddress); - if (dwAddrBase) { - return dwAddrBase; - } - if (VirtualQueryEx(hProcess, (void*)(ULONG_PTR)dwAddress, &memoryInfo, sizeof(memoryInfo))) { - char filePath[_MAX_PATH]; - char curDir[_MAX_PATH]; - char exePath[_MAX_PATH]; - DWORD size = GetModuleFileNameA((HINSTANCE)memoryInfo.AllocationBase, filePath, sizeof(filePath)); - - // Save and restore current directory around SymLoadModule, see KB article Q189780 - GetCurrentDirectoryA(sizeof(curDir), curDir); - GetModuleFileNameA(NULL, exePath, sizeof(exePath)); + MEMORY_BASIC_INFORMATION memoryInfo; + ULONG_ADDR dwAddrBase = SymGetModuleBase(hProcess, dwAddress); + if (dwAddrBase) { + return dwAddrBase; + } + if (VirtualQueryEx(hProcess, (void*)(GC_ULONG_PTR)dwAddress, &memoryInfo, + sizeof(memoryInfo))) { + char filePath[_MAX_PATH]; + char curDir[_MAX_PATH]; + char exePath[_MAX_PATH]; + DWORD size = GetModuleFileNameA((HINSTANCE)memoryInfo.AllocationBase, + filePath, sizeof(filePath)); + + /* Save and restore current directory around SymLoadModule, see KB */ + /* article Q189780. */ + GetCurrentDirectoryA(sizeof(curDir), curDir); + GetModuleFileNameA(NULL, exePath, sizeof(exePath)); #if defined(_MSC_VER) && _MSC_VER == 1200 - /* use strcat for VC6 */ - strcat(exePath, "\\.."); + /* use strcat for VC6 */ + strcat(exePath, "\\.."); #else - strcat_s(exePath, sizeof(exePath), "\\.."); + strcat_s(exePath, sizeof(exePath), "\\.."); #endif /* _MSC_VER >= 1200 */ - SetCurrentDirectoryA(exePath); + SetCurrentDirectoryA(exePath); #ifdef _DEBUG - GetCurrentDirectoryA(sizeof(exePath), exePath); + GetCurrentDirectoryA(sizeof(exePath), exePath); #endif - SymLoadModule(hProcess, NULL, size ? filePath : NULL, NULL, (ULONG_ADDR)(ULONG_PTR)memoryInfo.AllocationBase, 0); - SetCurrentDirectoryA(curDir); - } - return (ULONG_ADDR)(ULONG_PTR)memoryInfo.AllocationBase; + SymLoadModule(hProcess, NULL, size ? filePath : NULL, NULL, + (ULONG_ADDR)(GC_ULONG_PTR)memoryInfo.AllocationBase, 0); + SetCurrentDirectoryA(curDir); + } + return (ULONG_ADDR)(GC_ULONG_PTR)memoryInfo.AllocationBase; } static ULONG_ADDR CheckAddress(void* address) { - ULONG_ADDR dwAddress = (ULONG_ADDR)(ULONG_PTR)address; - GetModuleBase(GetSymHandle(), dwAddress); - return dwAddress; + ULONG_ADDR dwAddress = (ULONG_ADDR)(GC_ULONG_PTR)address; + GetModuleBase(GetSymHandle(), dwAddress); + return dwAddress; } size_t GetStackFrames(size_t skip, void* frames[], size_t maxFrames) { - HANDLE hProcess = GetSymHandle(); - HANDLE hThread = GetCurrentThread(); - CONTEXT context; - context.ContextFlags = CONTEXT_FULL; - if (!GetThreadContext(hThread, &context)) { - return 0; - } - // GetThreadContext might return invalid context for the current thread + HANDLE hProcess = GetSymHandle(); + HANDLE hThread = GetCurrentThread(); + CONTEXT context; + context.ContextFlags = CONTEXT_FULL; + if (!GetThreadContext(hThread, &context)) { + return 0; + } + /* GetThreadContext might return invalid context for the current thread. */ #if defined(_M_IX86) __asm mov context.Ebp, ebp #endif - return GetStackFramesFromContext(hProcess, hThread, &context, skip + 1, frames, maxFrames); + return GetStackFramesFromContext(hProcess, hThread, &context, skip + 1, + frames, maxFrames); } -size_t GetStackFramesFromContext(HANDLE hProcess, HANDLE hThread, CONTEXT* context, size_t skip, void* frames[], size_t maxFrames) +size_t GetStackFramesFromContext(HANDLE hProcess, HANDLE hThread, + CONTEXT* context, size_t skip, + void* frames[], size_t maxFrames) { - size_t frameIndex; - DWORD machineType; - STACKFRAME stackFrame = { 0 }; - stackFrame.AddrPC.Mode = AddrModeFlat; + size_t frameIndex; + DWORD machineType; + STACKFRAME stackFrame = { 0 }; + stackFrame.AddrPC.Mode = AddrModeFlat; #if defined(_M_IX86) - machineType = IMAGE_FILE_MACHINE_I386; - stackFrame.AddrPC.Offset = context->Eip; - stackFrame.AddrStack.Mode = AddrModeFlat; - stackFrame.AddrStack.Offset = context->Esp; - stackFrame.AddrFrame.Mode = AddrModeFlat; - stackFrame.AddrFrame.Offset = context->Ebp; + machineType = IMAGE_FILE_MACHINE_I386; + stackFrame.AddrPC.Offset = context->Eip; + stackFrame.AddrStack.Mode = AddrModeFlat; + stackFrame.AddrStack.Offset = context->Esp; + stackFrame.AddrFrame.Mode = AddrModeFlat; + stackFrame.AddrFrame.Offset = context->Ebp; #elif defined(_M_MRX000) - machineType = IMAGE_FILE_MACHINE_R4000; - stackFrame.AddrPC.Offset = context->Fir; + machineType = IMAGE_FILE_MACHINE_R4000; + stackFrame.AddrPC.Offset = context->Fir; #elif defined(_M_ALPHA) - machineType = IMAGE_FILE_MACHINE_ALPHA; - stackFrame.AddrPC.Offset = (unsigned long)context->Fir; + machineType = IMAGE_FILE_MACHINE_ALPHA; + stackFrame.AddrPC.Offset = (unsigned long)context->Fir; #elif defined(_M_PPC) - machineType = IMAGE_FILE_MACHINE_POWERPC; - stackFrame.AddrPC.Offset = context->Iar; + machineType = IMAGE_FILE_MACHINE_POWERPC; + stackFrame.AddrPC.Offset = context->Iar; #elif defined(_M_IA64) - machineType = IMAGE_FILE_MACHINE_IA64; - stackFrame.AddrPC.Offset = context->StIIP; + machineType = IMAGE_FILE_MACHINE_IA64; + stackFrame.AddrPC.Offset = context->StIIP; #elif defined(_M_ALPHA64) - machineType = IMAGE_FILE_MACHINE_ALPHA64; - stackFrame.AddrPC.Offset = context->Fir; + machineType = IMAGE_FILE_MACHINE_ALPHA64; + stackFrame.AddrPC.Offset = context->Fir; #else #error Unknown CPU #endif - for (frameIndex = 0; frameIndex < maxFrames; ) { - BOOL bRet = StackWalk(machineType, hProcess, hThread, &stackFrame, &context, NULL, FunctionTableAccess, GetModuleBase, NULL); - if (!bRet) { - break; - } - if (skip) { - skip--; - } else { - frames[frameIndex++] = (void*)(ULONG_PTR)stackFrame.AddrPC.Offset; - } - } - return frameIndex; + for (frameIndex = 0; frameIndex < maxFrames; ) { + BOOL bRet = StackWalk(machineType, hProcess, hThread, &stackFrame, + &context, NULL, FunctionTableAccess, GetModuleBase, NULL); + if (!bRet) { + break; + } + if (skip) { + skip--; + } else { + frames[frameIndex++] = (void*)(GC_ULONG_PTR)stackFrame.AddrPC.Offset; + } + } + return frameIndex; } size_t GetModuleNameFromAddress(void* address, char* moduleName, size_t size) { - if (size) *moduleName = 0; - { - const char* sourceName; - IMAGEHLP_MODULE moduleInfo = { sizeof (moduleInfo) }; - if (!SymGetModuleInfo(GetSymHandle(), CheckAddress(address), &moduleInfo)) { - return 0; - } - sourceName = strrchr(moduleInfo.ImageName, '\\'); - if (sourceName) { - sourceName++; - } else { - sourceName = moduleInfo.ImageName; - } - if (size) { - strncpy(moduleName, sourceName, size)[size - 1] = 0; - } - return strlen(sourceName); - } + if (size) *moduleName = 0; + { + const char* sourceName; + IMAGEHLP_MODULE moduleInfo = { sizeof (moduleInfo) }; + if (!SymGetModuleInfo(GetSymHandle(), CheckAddress(address), + &moduleInfo)) { + return 0; + } + sourceName = strrchr(moduleInfo.ImageName, '\\'); + if (sourceName) { + sourceName++; + } else { + sourceName = moduleInfo.ImageName; + } + if (size) { + strncpy(moduleName, sourceName, size)[size - 1] = 0; + } + return strlen(sourceName); + } } size_t GetModuleNameFromStack(size_t skip, char* moduleName, size_t size) { - void* address = NULL; - GetStackFrames(skip + 1, &address, 1); - if (address) { - return GetModuleNameFromAddress(address, moduleName, size); - } - return 0; + void* address = NULL; + GetStackFrames(skip + 1, &address, 1); + if (address) { + return GetModuleNameFromAddress(address, moduleName, size); + } + return 0; } -size_t GetSymbolNameFromAddress(void* address, char* symbolName, size_t size, size_t* offsetBytes) +size_t GetSymbolNameFromAddress(void* address, char* symbolName, size_t size, + size_t* offsetBytes) { - if (size) *symbolName = 0; - if (offsetBytes) *offsetBytes = 0; - __try { - ULONG_ADDR dwOffset = 0; - union { - IMAGEHLP_SYMBOL sym; - char symNameBuffer[sizeof(IMAGEHLP_SYMBOL) + MAX_SYM_NAME]; - } u; - u.sym.SizeOfStruct = sizeof(u.sym); - u.sym.MaxNameLength = sizeof(u.symNameBuffer) - sizeof(u.sym); - - if (!SymGetSymFromAddr(GetSymHandle(), CheckAddress(address), &dwOffset, &u.sym)) { - return 0; - } else { - const char* sourceName = u.sym.Name; - char undName[1024]; - if (UnDecorateSymbolName(u.sym.Name, undName, sizeof(undName), UNDNAME_NO_MS_KEYWORDS | UNDNAME_NO_ACCESS_SPECIFIERS)) { - sourceName = undName; - } else if (SymUnDName(&u.sym, undName, sizeof(undName))) { - sourceName = undName; - } - if (offsetBytes) { - *offsetBytes = dwOffset; - } - if (size) { - strncpy(symbolName, sourceName, size)[size - 1] = 0; - } - return strlen(sourceName); - } - } __except (EXCEPTION_EXECUTE_HANDLER) { - SetLastError(GetExceptionCode()); - } - return 0; + if (size) *symbolName = 0; + if (offsetBytes) *offsetBytes = 0; + __try { + ULONG_ADDR dwOffset = 0; + union { + IMAGEHLP_SYMBOL sym; + char symNameBuffer[sizeof(IMAGEHLP_SYMBOL) + MAX_SYM_NAME]; + } u; + u.sym.SizeOfStruct = sizeof(u.sym); + u.sym.MaxNameLength = sizeof(u.symNameBuffer) - sizeof(u.sym); + + if (!SymGetSymFromAddr(GetSymHandle(), CheckAddress(address), &dwOffset, + &u.sym)) { + return 0; + } else { + const char* sourceName = u.sym.Name; + char undName[1024]; + if (UnDecorateSymbolName(u.sym.Name, undName, sizeof(undName), + UNDNAME_NO_MS_KEYWORDS | UNDNAME_NO_ACCESS_SPECIFIERS)) { + sourceName = undName; + } else if (SymUnDName(&u.sym, undName, sizeof(undName))) { + sourceName = undName; + } + if (offsetBytes) { + *offsetBytes = dwOffset; + } + if (size) { + strncpy(symbolName, sourceName, size)[size - 1] = 0; + } + return strlen(sourceName); + } + } __except (EXCEPTION_EXECUTE_HANDLER) { + SetLastError(GetExceptionCode()); + } + return 0; } -size_t GetSymbolNameFromStack(size_t skip, char* symbolName, size_t size, size_t* offsetBytes) +size_t GetSymbolNameFromStack(size_t skip, char* symbolName, size_t size, + size_t* offsetBytes) { - void* address = NULL; - GetStackFrames(skip + 1, &address, 1); - if (address) { - return GetSymbolNameFromAddress(address, symbolName, size, offsetBytes); - } - return 0; + void* address = NULL; + GetStackFrames(skip + 1, &address, 1); + if (address) { + return GetSymbolNameFromAddress(address, symbolName, size, offsetBytes); + } + return 0; } -size_t GetFileLineFromAddress(void* address, char* fileName, size_t size, size_t* lineNumber, size_t* offsetBytes) +size_t GetFileLineFromAddress(void* address, char* fileName, size_t size, + size_t* lineNumber, size_t* offsetBytes) { - if (size) *fileName = 0; - if (lineNumber) *lineNumber = 0; - if (offsetBytes) *offsetBytes = 0; - { - char* sourceName; - IMAGEHLP_LINE line = { sizeof (line) }; - ULONG_PTR dwOffset = 0; - if (!SymGetLineFromAddr(GetSymHandle(), CheckAddress(address), &dwOffset, &line)) { - return 0; - } - if (lineNumber) { - *lineNumber = line.LineNumber; - } - if (offsetBytes) { - *offsetBytes = dwOffset; - } - sourceName = line.FileName; - // TODO: resolve relative filenames, found in 'source directories' registered with MSVC IDE. - if (size) { - strncpy(fileName, sourceName, size)[size - 1] = 0; - } - return strlen(sourceName); - } + if (size) *fileName = 0; + if (lineNumber) *lineNumber = 0; + if (offsetBytes) *offsetBytes = 0; + { + char* sourceName; + IMAGEHLP_LINE line = { sizeof (line) }; + GC_ULONG_PTR dwOffset = 0; + if (!SymGetLineFromAddr(GetSymHandle(), CheckAddress(address), &dwOffset, + &line)) { + return 0; + } + if (lineNumber) { + *lineNumber = line.LineNumber; + } + if (offsetBytes) { + *offsetBytes = dwOffset; + } + sourceName = line.FileName; + /* TODO: resolve relative filenames, found in 'source directories' */ + /* registered with MSVC IDE. */ + if (size) { + strncpy(fileName, sourceName, size)[size - 1] = 0; + } + return strlen(sourceName); + } } -size_t GetFileLineFromStack(size_t skip, char* fileName, size_t size, size_t* lineNumber, size_t* offsetBytes) +size_t GetFileLineFromStack(size_t skip, char* fileName, size_t size, + size_t* lineNumber, size_t* offsetBytes) { - void* address = NULL; - GetStackFrames(skip + 1, &address, 1); - if (address) { - return GetFileLineFromAddress(address, fileName, size, lineNumber, offsetBytes); - } - return 0; + void* address = NULL; + GetStackFrames(skip + 1, &address, 1); + if (address) { + return GetFileLineFromAddress(address, fileName, size, lineNumber, + offsetBytes); + } + return 0; } -size_t GetDescriptionFromAddress(void* address, const char* format, char* buffer, size_t size) +size_t GetDescriptionFromAddress(void* address, const char* format, + char* buffer, size_t size) { - char*const begin = buffer; - char*const end = buffer + size; - size_t line_number = 0; - char str[128]; - - if (size) { - *buffer = 0; - } - buffer += GetFileLineFromAddress(address, buffer, size, &line_number, NULL); - size = end < buffer ? 0 : end - buffer; - - if (line_number) { - wsprintf(str, "(%d) : ", line_number); - if (size) { - strncpy(buffer, str, size)[size - 1] = 0; - } - buffer += strlen(str); - size = end < buffer ? 0 : end - buffer; - } - - if (size) { - strncpy(buffer, "at ", size)[size - 1] = 0; - } - buffer += strlen("at "); - size = end < buffer ? 0 : end - buffer; - - buffer += GetSymbolNameFromAddress(address, buffer, size, NULL); - size = end < buffer ? 0 : end - buffer; - - if (size) { - strncpy(buffer, " in ", size)[size - 1] = 0; - } - buffer += strlen(" in "); - size = end < buffer ? 0 : end - buffer; - - buffer += GetModuleNameFromAddress(address, buffer, size); - size = end < buffer ? 0 : end - buffer; - - return buffer - begin; + char*const begin = buffer; + char*const end = buffer + size; + size_t line_number = 0; + char str[128]; + + if (size) { + *buffer = 0; + } + buffer += GetFileLineFromAddress(address, buffer, size, &line_number, NULL); + size = end < buffer ? 0 : end - buffer; + + if (line_number) { + wsprintf(str, "(%d) : ", line_number); + if (size) { + strncpy(buffer, str, size)[size - 1] = 0; + } + buffer += strlen(str); + size = end < buffer ? 0 : end - buffer; + } + + if (size) { + strncpy(buffer, "at ", size)[size - 1] = 0; + } + buffer += strlen("at "); + size = end < buffer ? 0 : end - buffer; + + buffer += GetSymbolNameFromAddress(address, buffer, size, NULL); + size = end < buffer ? 0 : end - buffer; + + if (size) { + strncpy(buffer, " in ", size)[size - 1] = 0; + } + buffer += strlen(" in "); + size = end < buffer ? 0 : end - buffer; + + buffer += GetModuleNameFromAddress(address, buffer, size); + size = end < buffer ? 0 : end - buffer; + + return buffer - begin; } -size_t GetDescriptionFromStack(void*const frames[], size_t count, const char* format, char* description[], size_t size) +size_t GetDescriptionFromStack(void* const frames[], size_t count, + const char* format, char* description[], + size_t size) { - char*const begin = (char*)description; - char*const end = begin + size; - char* buffer = begin + (count + 1) * sizeof(char*); - size_t i; - for (i = 0; i < count; ++i) { - if (description) description[i] = buffer; - size = end < buffer ? 0 : end - buffer; - buffer += 1 + GetDescriptionFromAddress(frames[i], NULL, buffer, size); - } - if (description) description[count] = NULL; - return buffer - begin; + char*const begin = (char*)description; + char*const end = begin + size; + char* buffer = begin + (count + 1) * sizeof(char*); + size_t i; + for (i = 0; i < count; ++i) { + if (description) description[i] = buffer; + size = end < buffer ? 0 : end - buffer; + buffer += 1 + GetDescriptionFromAddress(frames[i], NULL, buffer, size); + } + if (description) description[count] = NULL; + return buffer - begin; } /* Compatibility with <execinfo.h> */ int backtrace(void* addresses[], int count) { - return GetStackFrames(1, addresses, count); + return GetStackFrames(1, addresses, count); } char** backtrace_symbols(void*const* addresses, int count) { - size_t size = GetDescriptionFromStack(addresses, count, NULL, NULL, 0); - char** symbols = (char**)malloc(size); - GetDescriptionFromStack(addresses, count, NULL, symbols, size); - return symbols; + size_t size = GetDescriptionFromStack(addresses, count, NULL, NULL, 0); + char** symbols = (char**)malloc(size); + GetDescriptionFromStack(addresses, count, NULL, symbols, size); + return symbols; } #endif /* !_M_AMD64 */ |