From: Jinhyung Jo Date: Tue, 11 Oct 2016 11:06:06 +0000 (+0900) Subject: util: modify backtrace feature for Windows X-Git-Tag: Tizen_Studio_1.3_Release_p2.3.2~22^2~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1e884dfd8d10ad3c5cbd415467c1723b1e37c0f8;p=sdk%2Femulator%2Fqemu.git util: modify backtrace feature for Windows integrate the 32-bit & 64-bit implementation Change-Id: I7540eeec080ba7fb3f10dcbba663dc4d677b8db9 Signed-off-by: Jinhyung Jo Signed-off-by: Sooyoung Ha --- diff --git a/tizen/src/util/error_handler.c b/tizen/src/util/error_handler.c index 5a41b054ea..959594e83c 100644 --- a/tizen/src/util/error_handler.c +++ b/tizen/src/util/error_handler.c @@ -67,95 +67,30 @@ void enable_print_backtrace_at_normal_exit(void) #ifdef CONFIG_WIN32 static LPTOP_LEVEL_EXCEPTION_FILTER prevExceptionFilter; -/* Windows 32 bit */ -#ifndef _WIN64 -struct frame_layout { - void *pNext; - void *pReturnAddr; -}; - -static HMODULE get_module_handle(void *dwAddress) -{ - MEMORY_BASIC_INFORMATION Buffer; - return VirtualQuery((LPCVOID)dwAddress, &Buffer, sizeof(Buffer)) - ? (HMODULE)Buffer.AllocationBase : (HMODULE)0; -} - +/* The MSDN says as followed in "Updated Platform Support" page, + (https://msdn.microsoft.com/en-us/library/windows/desktop/ + ms681408(v=vs.85).aspx) + "Where necessary, the DbgHelp library has been widened to support both 32- + and 64-bit Windows. The original function and structure definitions are + still in DbgHelp.h, but there are also updated versions of these + definitions that are compatible with 64-bit Windows. If you use the updated + functions in your code, it can be compiled for both 32- and 64-bit Windows. + Your code will also be more efficient, since the original functions simply + call the updated functions to perform the work." + However, using the updated functinos does not work on the Windows 32-bit. + IMHO, in the MinGW cross compile environment rather than the Visual Studio + it does not compile correctly. + Thus, use explicitly. +*/ static void dump_backtrace(void *ptr) { - int nCount; - void *pTopFrame; - struct frame_layout currentFrame; - struct frame_layout *pCurrentFrame; - - char module_buf[1024]; - HMODULE hModule; - - PCONTEXT pContext = ptr; - if (!pContext) { - __asm__ __volatile__ ("movl %%ebp, %0" : "=m" (pTopFrame)); - } else { - pTopFrame = (void *)((PCONTEXT)pContext)->Ebp; - } - - if (pTopFrame == NULL) { - LOG_INFO("ebp is null, skip this for now\n"); - return ; - } - - nCount = 0; - currentFrame.pNext = ((struct frame_layout *)pTopFrame)->pNext; - currentFrame.pReturnAddr = ((struct frame_layout *)pTopFrame)->pReturnAddr; - pCurrentFrame = (struct frame_layout *)pTopFrame; - - if (pContext) { - memset(module_buf, 0, sizeof(module_buf)); - hModule = get_module_handle((void *)((PCONTEXT)pContext)->Eip); - if (hModule) { - if (!GetModuleFileNameA(hModule, module_buf, sizeof(module_buf))) { - memset(module_buf, 0, sizeof(module_buf)); - } - } - LOG_SEVERE("#%04d 0x%08x from %s\n", - nCount, ((PCONTEXT)pContext)->Eip, module_buf); - nCount++; - } - - while (1) { - if (((void *)pCurrentFrame < pTopFrame) - || ((void *)pCurrentFrame >= (void *)0xC0000000) - || !currentFrame.pReturnAddr) { - break; - } - - memset(module_buf, 0, sizeof(module_buf)); - hModule = get_module_handle(currentFrame.pReturnAddr); - if (hModule) { - if (!GetModuleFileNameA(hModule, module_buf, sizeof(module_buf))) { - memset(module_buf, 0, sizeof(module_buf)); - } - } - LOG_SEVERE("#%04d 0x%08x from %s\n", - nCount, currentFrame.pReturnAddr, module_buf); - - if (!ReadProcessMemory(GetCurrentProcess(), currentFrame.pNext, - (void *)¤tFrame, sizeof(struct frame_layout), NULL)) { - break; - } - pCurrentFrame = (struct frame_layout *)pCurrentFrame->pNext; - - nCount++; - } -} - +#ifdef _WIN64 + STACKFRAME64 frame; #else - -/* Windows 64 bit */ -static void dump_backtrace(void *ptr) -{ + STACKFRAME frame; +#endif int i; DWORD image; - STACKFRAME64 frame; CONTEXT context; HANDLE hProcess = GetCurrentProcess(); HANDLE hThread = GetCurrentThread(); @@ -168,9 +103,9 @@ static void dump_backtrace(void *ptr) CopyMemory(&context, ptr, sizeof(CONTEXT)); } - SymSetOptions(SYMOPT_LOAD_LINES); SymInitialize(hProcess, NULL, TRUE); +#ifdef _WIN64 ZeroMemory(&frame, sizeof(STACKFRAME64)); image = IMAGE_FILE_MACHINE_AMD64; frame.AddrPC.Offset = context.Rip; @@ -179,48 +114,82 @@ static void dump_backtrace(void *ptr) frame.AddrFrame.Mode = AddrModeFlat; frame.AddrStack.Offset = context.Rsp; frame.AddrStack.Mode = AddrModeFlat; +#else + ZeroMemory(&frame, sizeof(STACKFRAME)); + image = IMAGE_FILE_MACHINE_I386; + frame.AddrPC.Offset = context.Eip; + frame.AddrPC.Mode = AddrModeFlat; + frame.AddrFrame.Offset = context.Ebp; + frame.AddrFrame.Mode = AddrModeFlat; + frame.AddrStack.Offset = context.Esp; + frame.AddrStack.Mode = AddrModeFlat; +#endif i = 0; while (1) { +#ifdef _WIN64 BOOL result = StackWalk64(image, hProcess, hThread, &frame, &context, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL); +#else + BOOL result = StackWalk(image, hProcess, hThread, + &frame, &context, NULL, + SymFunctionTableAccess, + SymGetModuleBase, NULL); +#endif if (!result) { break; } - TCHAR buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)]; + TCHAR buffer[sizeof(SYMBOL_INFO) + (MAX_SYM_NAME - 1) * sizeof(TCHAR)]; PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer; pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); pSymbol->MaxNameLen = MAX_SYM_NAME; DWORD64 displacement = 0; TCHAR pFileName[MAX_PATH] = {0, }; +#ifdef _WIN64 DWORD64 dwBase = SymGetModuleBase64(hProcess, frame.AddrPC.Offset); +#else + DWORD dwBase = SymGetModuleBase(hProcess, frame.AddrPC.Offset); +#endif if (dwBase) { HMODULE hModule = (HMODULE)((DWORD_PTR)dwBase); if (!GetModuleFileNameA(hModule, pFileName, MAX_PATH)) { snprintf(pFileName, MAX_PATH, "Unknown Module"); } } + /* TODO: take the symbols for the static functions + without import .pdb */ if (SymFromAddr(hProcess, frame.AddrPC.Offset, &displacement, pSymbol)) { - LOG_SEVERE("#%04d 0x%016x in %s from %s\n", +#ifdef _WIN64 + LOG_INFO("#%04d 0x%016I64x in %s from %s\n", +#else + LOG_INFO("#%04d 0x%08x in %s from %s\n", +#endif i, frame.AddrPC.Offset, pSymbol->Name, pFileName); } else { - LOG_SEVERE("#%04d 0x%016x in ???????? from %s\n", +#ifdef _WIN64 + LOG_INFO("#%04d 0x%016I64x in ???????? from %s\n", +#else + LOG_INFO("#%04d 0x%08x in ???????? from %s\n", +#endif i, frame.AddrPC.Offset, pFileName); } i++; } SymCleanup(hProcess); } -#endif static WINAPI LONG maru_unhandled_exception_filter(LPEXCEPTION_POINTERS pException) { - LOG_SEVERE("Exception occurred: Code[0x%x], Address[0x%016x]\n", +#ifdef _WIN64 + LOG_SEVERE("Exception occurred: Code[0x%x], Address[0x%016I64x]\n", +#else + LOG_SEVERE("Exception occurred: Code[0x%x], Address[0x%08x]\n", +#endif pException->ExceptionRecord->ExceptionCode, pException->ExceptionRecord->ExceptionAddress); @@ -250,9 +219,9 @@ static void dump_backtrace(void *ptr) int ndepth = backtrace(trace, 1024); char **syms = backtrace_symbols(trace, ndepth); - LOG_SEVERE("Backtrace depth is %d\n", ndepth); + LOG_INFO("Backtrace depth is %d\n", ndepth); for (i = 0; i < ndepth; i++) { - LOG_SEVERE("#%04d %s\n", i, syms[i]); + LOG_INFO("#%04d %s\n", i, syms[i]); } free(syms); }