util: modify backtrace feature for Windows
authorJinhyung Jo <jinhyung.jo@samsung.com>
Tue, 11 Oct 2016 11:06:06 +0000 (20:06 +0900)
committerSooyoung Ha <yoosah.ha@samsung.com>
Thu, 13 Oct 2016 02:52:43 +0000 (11:52 +0900)
integrate the 32-bit & 64-bit implementation

Change-Id: I7540eeec080ba7fb3f10dcbba663dc4d677b8db9
Signed-off-by: Jinhyung Jo <jinhyung.jo@samsung.com>
Signed-off-by: Sooyoung Ha <yoosah.ha@samsung.com>
tizen/src/util/error_handler.c

index 5a41b05..959594e 100644 (file)
@@ -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 *)&currentFrame, 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);
 }