From 174a4fb7fe6f20a418f5ca9ab8ab0568960ef104 Mon Sep 17 00:00:00 2001 From: Ralf Habacker Date: Tue, 17 Nov 2015 00:17:12 +0100 Subject: [PATCH] Refactor back trace generator - indention fix - link to dbghelp library on runtime - x86_64 support Bug: https://bugs.freedesktop.org/show_bug.cgi?id=92721 --- cmake/dbus/CMakeLists.txt | 2 +- dbus/dbus-sysdeps-win.c | 333 +++++++++++++--------------------------------- 2 files changed, 95 insertions(+), 240 deletions(-) diff --git a/cmake/dbus/CMakeLists.txt b/cmake/dbus/CMakeLists.txt index 1701408..851ec60 100644 --- a/cmake/dbus/CMakeLists.txt +++ b/cmake/dbus/CMakeLists.txt @@ -275,7 +275,7 @@ if(WIN32) if(WINCE) target_link_libraries(dbus-1 ws2) else(WINCE) - target_link_libraries(dbus-1 ws2_32 advapi32 netapi32 iphlpapi) + target_link_libraries(dbus-1 ws2_32 advapi32 netapi32 iphlpapi dbghelp) endif(WINCE) else(WIN32) if(DEFINED DBUS_LIBRARY_REVISION) diff --git a/dbus/dbus-sysdeps-win.c b/dbus/dbus-sysdeps-win.c index 71233d7..adce3b5 100644 --- a/dbus/dbus-sysdeps-win.c +++ b/dbus/dbus-sysdeps-win.c @@ -2405,201 +2405,47 @@ _dbus_delete_file (const DBusString *filename, #define DPRINTF(fmt, ...) fprintf (stderr, fmt, ##__VA_ARGS__) -#ifdef _MSC_VER -#define BOOL int - -#define __i386__ -#endif - -//#define MAKE_FUNCPTR(f) static typeof(f) * p##f - -//MAKE_FUNCPTR(StackWalk); -//MAKE_FUNCPTR(SymGetModuleBase); -//MAKE_FUNCPTR(SymFunctionTableAccess); -//MAKE_FUNCPTR(SymInitialize); -//MAKE_FUNCPTR(SymGetSymFromAddr); -//MAKE_FUNCPTR(SymGetModuleInfo); -static BOOL (WINAPI *pStackWalk)( - DWORD MachineType, - HANDLE hProcess, - HANDLE hThread, - LPSTACKFRAME StackFrame, - PVOID ContextRecord, - PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine, - PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine, - PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine, - PTRANSLATE_ADDRESS_ROUTINE TranslateAddress -); -#ifdef _WIN64 -static DWORD64 (WINAPI *pSymGetModuleBase)( - HANDLE hProcess, - DWORD64 dwAddr -); -static PVOID (WINAPI *pSymFunctionTableAccess)( - HANDLE hProcess, - DWORD64 AddrBase -); -#else -static DWORD (WINAPI *pSymGetModuleBase)( - HANDLE hProcess, - DWORD dwAddr -); -static PVOID (WINAPI *pSymFunctionTableAccess)( - HANDLE hProcess, - DWORD AddrBase -); -#endif -static BOOL (WINAPI *pSymInitialize)( - HANDLE hProcess, - PSTR UserSearchPath, - BOOL fInvadeProcess -); -static BOOL (WINAPI *pSymGetSymFromAddr)( - HANDLE hProcess, - DWORD Address, - PDWORD Displacement, - PIMAGEHLP_SYMBOL Symbol -); -static BOOL (WINAPI *pSymGetModuleInfo)( - HANDLE hProcess, - DWORD dwAddr, - PIMAGEHLP_MODULE ModuleInfo -); -static DWORD (WINAPI *pSymSetOptions)( - DWORD SymOptions -); -static BOOL (WINAPI *pSymGetLineFromAddr)( - HANDLE hProcess, - DWORD dwAddr, - PDWORD pdwDisplacement, - PIMAGEHLP_LINE Line -); - -static BOOL init_backtrace() -{ - HMODULE hmodDbgHelp = LoadLibraryA("dbghelp"); -/* - #define GETFUNC(x) \ - p##x = (typeof(x)*)GetProcAddress(hmodDbgHelp, #x); \ - if (!p##x) \ - { \ - return FALSE; \ - } - */ - - -// GETFUNC(StackWalk); -// GETFUNC(SymGetModuleBase); -// GETFUNC(SymFunctionTableAccess); -// GETFUNC(SymInitialize); -// GETFUNC(SymGetSymFromAddr); -// GETFUNC(SymGetModuleInfo); - -#define FUNC(x) #x - - pStackWalk = (BOOL (WINAPI *)( -DWORD MachineType, -HANDLE hProcess, -HANDLE hThread, -LPSTACKFRAME StackFrame, -PVOID ContextRecord, -PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine, -PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine, -PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine, -PTRANSLATE_ADDRESS_ROUTINE TranslateAddress -))GetProcAddress (hmodDbgHelp, FUNC(StackWalk)); -#ifdef _WIN64 - pSymGetModuleBase=(DWORD64 (WINAPI *)( - HANDLE hProcess, - DWORD64 dwAddr -))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleBase)); - pSymFunctionTableAccess=(PVOID (WINAPI *)( - HANDLE hProcess, - DWORD64 AddrBase -))GetProcAddress (hmodDbgHelp, FUNC(SymFunctionTableAccess)); -#else - pSymGetModuleBase=(DWORD (WINAPI *)( - HANDLE hProcess, - DWORD dwAddr -))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleBase)); - pSymFunctionTableAccess=(PVOID (WINAPI *)( - HANDLE hProcess, - DWORD AddrBase -))GetProcAddress (hmodDbgHelp, FUNC(SymFunctionTableAccess)); -#endif - pSymInitialize = (BOOL (WINAPI *)( - HANDLE hProcess, - PSTR UserSearchPath, - BOOL fInvadeProcess -))GetProcAddress (hmodDbgHelp, FUNC(SymInitialize)); - pSymGetSymFromAddr = (BOOL (WINAPI *)( - HANDLE hProcess, - DWORD Address, - PDWORD Displacement, - PIMAGEHLP_SYMBOL Symbol -))GetProcAddress (hmodDbgHelp, FUNC(SymGetSymFromAddr)); - pSymGetModuleInfo = (BOOL (WINAPI *)( - HANDLE hProcess, - DWORD dwAddr, - PIMAGEHLP_MODULE ModuleInfo -))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleInfo)); -pSymSetOptions = (DWORD (WINAPI *)( -DWORD SymOptions -))GetProcAddress (hmodDbgHelp, FUNC(SymSetOptions)); - pSymGetLineFromAddr = (BOOL (WINAPI *)( - HANDLE hProcess, - DWORD dwAddr, - PDWORD pdwDisplacement, - PIMAGEHLP_LINE Line -))GetProcAddress (hmodDbgHelp, FUNC(SymGetLineFromAddr)); - - pSymSetOptions(SYMOPT_UNDNAME | SYMOPT_LOAD_LINES); - - pSymInitialize(GetCurrentProcess(), NULL, TRUE); - - return TRUE; -} - -static void dump_backtrace_for_thread(HANDLE hThread) +static void dump_backtrace_for_thread (HANDLE hThread) { - STACKFRAME sf; - CONTEXT context; - DWORD dwImageType; - int i = 0; + STACKFRAME sf; + CONTEXT context; + DWORD dwImageType; + DWORD64 old_address = 0; + int i = 0; + + SymSetOptions (SYMOPT_UNDNAME | SYMOPT_LOAD_LINES); - if (!pStackWalk) - if (!init_backtrace()) - return; + SymInitialize (GetCurrentProcess (), NULL, TRUE); - /* can't use this function for current thread as GetThreadContext - * doesn't support getting context from current thread */ - if (hThread == GetCurrentThread()) - return; + /* can't use this function for current thread as GetThreadContext + * doesn't support getting context from current thread */ + if (hThread == GetCurrentThread ()) + return; - DPRINTF("Backtrace:\n"); + DPRINTF ("Backtrace:\n"); - _DBUS_ZERO(context); - context.ContextFlags = CONTEXT_FULL; + _DBUS_ZERO (context); + context.ContextFlags = CONTEXT_FULL; - SuspendThread(hThread); + SuspendThread (hThread); - if (!GetThreadContext(hThread, &context)) + if (!GetThreadContext (hThread, &context)) { - DPRINTF("Couldn't get thread context (error %ld)\n", GetLastError()); - ResumeThread(hThread); - return; + DPRINTF ("Couldn't get thread context (error %ld)\n", GetLastError ()); + ResumeThread (hThread); + return; } - _DBUS_ZERO(sf); + _DBUS_ZERO (sf); #ifdef __i386__ - sf.AddrFrame.Offset = context.Ebp; - sf.AddrFrame.Mode = AddrModeFlat; - sf.AddrPC.Offset = context.Eip; - sf.AddrPC.Mode = AddrModeFlat; - dwImageType = IMAGE_FILE_MACHINE_I386; + dwImageType = IMAGE_FILE_MACHINE_I386; + sf.AddrFrame.Offset = context.Ebp; + sf.AddrFrame.Mode = AddrModeFlat; + sf.AddrPC.Offset = context.Eip; + sf.AddrPC.Mode = AddrModeFlat; #elif _M_X64 - dwImageType = IMAGE_FILE_MACHINE_AMD64; + dwImageType = IMAGE_FILE_MACHINE_AMD64; sf.AddrPC.Offset = context.Rip; sf.AddrPC.Mode = AddrModeFlat; sf.AddrFrame.Offset = context.Rsp; @@ -2607,7 +2453,7 @@ static void dump_backtrace_for_thread(HANDLE hThread) sf.AddrStack.Offset = context.Rsp; sf.AddrStack.Mode = AddrModeFlat; #elif _M_IA64 - dwImageType = IMAGE_FILE_MACHINE_IA64; + dwImageType = IMAGE_FILE_MACHINE_IA64; sf.AddrPC.Offset = context.StIIP; sf.AddrPC.Mode = AddrModeFlat; sf.AddrFrame.Offset = context.IntSp; @@ -2619,85 +2465,94 @@ static void dump_backtrace_for_thread(HANDLE hThread) #else # error You need to fill in the STACKFRAME structure for your architecture #endif + /* + backtrace format +
[ [+offset] ] [ '[' ':' ']' ] [ 'in' ] + example: + 6 0xf75ade6b wine_switch_to_stack+0x2a [/usr/src/debug/wine-snapshot/libs/wine/port.c:59] in libwine.so.1 + */ + while (StackWalk (dwImageType, GetCurrentProcess (), + hThread, &sf, &context, NULL, SymFunctionTableAccess, + SymGetModuleBase, NULL)) + { + BYTE buffer[256]; + IMAGEHLP_SYMBOL *pSymbol = (IMAGEHLP_SYMBOL *)buffer; +#ifdef _IMAGEHLP64 + DWORD64 displacement; +#define FORMAT "I64d" +#else + DWORD displacement; +#define FORMAT "lx" +#endif + IMAGEHLP_LINE line; + IMAGEHLP_MODULE moduleInfo; + DWORD dwDisplacement; + +#ifdef _IMAGEHLP64 + /* wine hack */ + if (old_address == sf.AddrPC.Offset) + break; +#endif + pSymbol->SizeOfStruct = sizeof (IMAGEHLP_SYMBOL); + pSymbol->MaxNameLength = sizeof (buffer) - sizeof (IMAGEHLP_SYMBOL) + 1; + if (SymGetSymFromAddr (GetCurrentProcess (), sf.AddrPC.Offset, + &displacement, pSymbol)) + { + if (displacement) + DPRINTF ("%3d %s+0x%" FORMAT, i++, pSymbol->Name, displacement); + else + DPRINTF ("%3d %s", i++, pSymbol->Name); + } + else + DPRINTF ("%3d 0x%" FORMAT, i++, sf.AddrPC.Offset); - /* - backtrace format -
[ [+offset] ] [ '[' ':' ']' ] [ 'in' ] - example: - 6 0xf75ade6b wine_switch_to_stack+0x2a [/usr/src/debug/wine-snapshot/libs/wine/port.c:59] in libwine.so.1 - */ - while (pStackWalk(dwImageType, GetCurrentProcess(), - hThread, &sf, &context, NULL, pSymFunctionTableAccess, - pSymGetModuleBase, NULL)) - { - BYTE buffer[256]; - IMAGEHLP_SYMBOL * pSymbol = (IMAGEHLP_SYMBOL *)buffer; - DWORD dwDisplacement; - IMAGEHLP_LINE line; - IMAGEHLP_MODULE moduleInfo; - - pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL); - pSymbol->MaxNameLength = sizeof(buffer) - sizeof(IMAGEHLP_SYMBOL) + 1; - - if (pSymGetSymFromAddr(GetCurrentProcess(), sf.AddrPC.Offset, - &dwDisplacement, pSymbol)) - { - if (dwDisplacement) - DPRINTF ("%3d %s+0x%lx", i++, pSymbol->Name, dwDisplacement); - else - DPRINTF ("%3d %s", i++, pSymbol->Name); - } - else - DPRINTF ("%3d 0x%lx", i++, sf.AddrPC.Offset); - - line.SizeOfStruct = sizeof(IMAGEHLP_LINE); - if (pSymGetLineFromAddr(GetCurrentProcess(), sf.AddrPC.Offset, &dwDisplacement, &line) == TRUE) - { - DPRINTF (" [%s:%ld]", line.FileName, line.LineNumber); - } - - moduleInfo.SizeOfStruct = sizeof(moduleInfo); - if (pSymGetModuleInfo(GetCurrentProcess(), sf.AddrPC.Offset, &moduleInfo)) - { - DPRINTF (" in %s\n", moduleInfo.ModuleName); - } - } + line.SizeOfStruct = sizeof (IMAGEHLP_LINE); + if (SymGetLineFromAddr (GetCurrentProcess (), sf.AddrPC.Offset, &dwDisplacement, &line)) + { + DPRINTF (" [%s:%ld]", line.FileName, line.LineNumber); + } - ResumeThread(hThread); + moduleInfo.SizeOfStruct = sizeof (moduleInfo); + if (SymGetModuleInfo (GetCurrentProcess (), sf.AddrPC.Offset, &moduleInfo)) + { + DPRINTF (" in %s\n", moduleInfo.ModuleName); + } + old_address = sf.AddrPC.Offset; + } + ResumeThread (hThread); } -static DWORD WINAPI dump_thread_proc(LPVOID lpParameter) +static DWORD WINAPI dump_thread_proc (LPVOID lpParameter) { - dump_backtrace_for_thread((HANDLE)lpParameter); + dump_backtrace_for_thread ((HANDLE)lpParameter); return 0; } /* cannot get valid context from current thread, so we have to execute * backtrace from another thread */ -static void dump_backtrace() +static void dump_backtrace () { HANDLE hCurrentThread; HANDLE hThread; DWORD dwThreadId; - DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), - GetCurrentProcess(), &hCurrentThread, 0, FALSE, DUPLICATE_SAME_ACCESS); - hThread = CreateThread(NULL, 0, dump_thread_proc, (LPVOID)hCurrentThread, + DuplicateHandle (GetCurrentProcess (), GetCurrentThread (), + GetCurrentProcess (), &hCurrentThread, 0, FALSE, DUPLICATE_SAME_ACCESS); + hThread = CreateThread (NULL, 0, dump_thread_proc, (LPVOID)hCurrentThread, 0, &dwThreadId); - WaitForSingleObject(hThread, INFINITE); - CloseHandle(hThread); - CloseHandle(hCurrentThread); + WaitForSingleObject (hThread, INFINITE); + CloseHandle (hThread); + CloseHandle (hCurrentThread); } #endif #endif /* asserts or tests enabled */ #ifdef BACKTRACES -void _dbus_print_backtrace(void) +void _dbus_print_backtrace (void) { - init_backtrace(); - dump_backtrace(); + dump_backtrace (); } #else -void _dbus_print_backtrace(void) +void _dbus_print_backtrace (void) { _dbus_verbose (" D-Bus not compiled with backtrace support\n"); } -- 1.8.4.5