X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcommon%2Flogbacktrace_win.cpp;h=06a6f80e2fc672d7cbb9a66f4ac08c44acd52880;hp=b12c15dc2e2fbc946cc41738e1d7deef81e1c3f8;hb=694f9bfbf7f1af19108461c7e00d133e55082bce;hpb=61c8d84d1c849373e0f115dc748ed45cff95287d diff --git a/src/common/logbacktrace_win.cpp b/src/common/logbacktrace_win.cpp index b12c15dc..06a6f80e 100644 --- a/src/common/logbacktrace_win.cpp +++ b/src/common/logbacktrace_win.cpp @@ -28,191 +28,197 @@ #include #include -void loadHelpStackFrame(IMAGEHLP_STACK_FRAME &ihsf, const STACKFRAME64 &stackFrame) { - ZeroMemory(&ihsf, sizeof(IMAGEHLP_STACK_FRAME)); - ihsf.InstructionOffset = stackFrame.AddrPC.Offset; - ihsf.FrameOffset = stackFrame.AddrFrame.Offset; +void loadHelpStackFrame(IMAGEHLP_STACK_FRAME &ihsf, const STACKFRAME64 &stackFrame) +{ + ZeroMemory(&ihsf, sizeof(IMAGEHLP_STACK_FRAME)); + ihsf.InstructionOffset = stackFrame.AddrPC.Offset; + ihsf.FrameOffset = stackFrame.AddrFrame.Offset; } -BOOL CALLBACK EnumSymbolsCB(PSYMBOL_INFO symInfo, ULONG size, PVOID user) { - QStringList *params = (QStringList *)user; - if(symInfo->Flags & SYMFLAG_PARAMETER) { - params->append(symInfo->Name); - } - return TRUE; + +BOOL CALLBACK EnumSymbolsCB(PSYMBOL_INFO symInfo, ULONG size, PVOID user) +{ + QStringList *params = (QStringList *)user; + if (symInfo->Flags & SYMFLAG_PARAMETER) { + params->append(symInfo->Name); + } + return TRUE; } struct EnumModulesContext { - HANDLE hProcess; - QTextStream &stream; - EnumModulesContext(HANDLE hProcess, QTextStream &stream) : hProcess(hProcess), stream(stream) {} + HANDLE hProcess; + QTextStream &stream; + EnumModulesContext(HANDLE hProcess, QTextStream &stream) : hProcess(hProcess), stream(stream) {} }; -BOOL CALLBACK EnumModulesCB(LPCSTR ModuleName, DWORD64 BaseOfDll, PVOID UserContext) { - IMAGEHLP_MODULE64 mod; - EnumModulesContext *context = (EnumModulesContext *)UserContext; - mod.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); - if(SymGetModuleInfo64(context->hProcess, BaseOfDll, &mod)) { - QString line = QString("%1 0x%2 Image: %3").arg(mod.ModuleName, -14) - .arg(BaseOfDll, 8, 16, QLatin1Char('0')) - .arg(mod.LoadedImageName); - // qDebug() << qPrintable(line); - context->stream << line << '\n'; - - QString pdbName(mod.LoadedPdbName); - if(!pdbName.isEmpty()) { - QString line2 = QString("%1 %2").arg("", 32).arg(pdbName); - // qDebug() << qPrintable(line2); - context->stream << line2 << '\n'; +BOOL CALLBACK EnumModulesCB(LPCSTR ModuleName, DWORD64 BaseOfDll, PVOID UserContext) +{ + IMAGEHLP_MODULE64 mod; + EnumModulesContext *context = (EnumModulesContext *)UserContext; + mod.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); + if (SymGetModuleInfo64(context->hProcess, BaseOfDll, &mod)) { + QString line = QString("%1 0x%2 Image: %3").arg(mod.ModuleName, -14) + .arg(BaseOfDll, 8, 16, QLatin1Char('0')) + .arg(mod.LoadedImageName); + // qDebug() << qPrintable(line); + context->stream << line << '\n'; + + QString pdbName(mod.LoadedPdbName); + if (!pdbName.isEmpty()) { + QString line2 = QString("%1 %2").arg("", 32).arg(pdbName); + // qDebug() << qPrintable(line2); + context->stream << line2 << '\n'; + } } - } - return TRUE; + return TRUE; } - -#if defined( _M_IX86 ) && defined(Q_CC_MSVC) - // Disable global optimization and ignore /GS waning caused by - // inline assembly. - // not needed with mingw cause we can tell mingw which registers we use +#if defined(_M_IX86) && defined(Q_CC_MSVC) +// Disable global optimization and ignore /GS waning caused by +// inline assembly. +// not needed with mingw cause we can tell mingw which registers we use #pragma optimize("g", off) #pragma warning(push) #pragma warning(disable : 4748) #endif -void Quassel::logBacktrace(const QString &filename) { - DWORD MachineType; - CONTEXT Context; - STACKFRAME64 StackFrame; +void Quassel::logBacktrace(const QString &filename) +{ + DWORD MachineType; + CONTEXT Context; + STACKFRAME64 StackFrame; #ifdef _M_IX86 ZeroMemory(&Context, sizeof(CONTEXT)); Context.ContextFlags = CONTEXT_CONTROL; - #ifdef __MINGW32__ - asm("Label:\n\t" - "movl %%ebp,%0;\n\t" - "movl %%esp,%1;\n\t" - "movl $Label,%%eax;\n\t" - "movl %%eax,%2;\n\t" - :"=r"(Context.Ebp),"=r"(Context.Esp),"=r"(Context.Eip) - ://no input - :"eax"); + asm ("Label:\n\t" + "movl %%ebp,%0;\n\t" + "movl %%esp,%1;\n\t" + "movl $Label,%%eax;\n\t" + "movl %%eax,%2;\n\t" + : "=r" (Context.Ebp), "=r" (Context.Esp), "=r" (Context.Eip) + : //no input + : "eax"); #else _asm { - Label: - mov [Context.Ebp], ebp; - mov [Context.Esp], esp; - mov eax, [Label]; - mov [Context.Eip], eax; +Label: + mov[Context.Ebp], ebp; + mov[Context.Esp], esp; + mov eax, [Label]; + mov[Context.Eip], eax; } #endif #else RtlCaptureContext(&Context); #endif - ZeroMemory(&StackFrame, sizeof(STACKFRAME64)); + ZeroMemory(&StackFrame, sizeof(STACKFRAME64)); #ifdef _M_IX86 - MachineType = IMAGE_FILE_MACHINE_I386; - StackFrame.AddrPC.Offset = Context.Eip; - StackFrame.AddrPC.Mode = AddrModeFlat; - StackFrame.AddrFrame.Offset = Context.Ebp; - StackFrame.AddrFrame.Mode = AddrModeFlat; - StackFrame.AddrStack.Offset = Context.Esp; - StackFrame.AddrStack.Mode = AddrModeFlat; + MachineType = IMAGE_FILE_MACHINE_I386; + StackFrame.AddrPC.Offset = Context.Eip; + StackFrame.AddrPC.Mode = AddrModeFlat; + StackFrame.AddrFrame.Offset = Context.Ebp; + StackFrame.AddrFrame.Mode = AddrModeFlat; + StackFrame.AddrStack.Offset = Context.Esp; + StackFrame.AddrStack.Mode = AddrModeFlat; #elif _M_X64 - MachineType = IMAGE_FILE_MACHINE_AMD64; - StackFrame.AddrPC.Offset = Context.Rip; - StackFrame.AddrPC.Mode = AddrModeFlat; - StackFrame.AddrFrame.Offset = Context.Rsp; - StackFrame.AddrFrame.Mode = AddrModeFlat; - StackFrame.AddrStack.Offset = Context.Rsp; - StackFrame.AddrStack.Mode = AddrModeFlat; + MachineType = IMAGE_FILE_MACHINE_AMD64; + StackFrame.AddrPC.Offset = Context.Rip; + StackFrame.AddrPC.Mode = AddrModeFlat; + StackFrame.AddrFrame.Offset = Context.Rsp; + StackFrame.AddrFrame.Mode = AddrModeFlat; + StackFrame.AddrStack.Offset = Context.Rsp; + StackFrame.AddrStack.Mode = AddrModeFlat; #elif _M_IA64 - MachineType = IMAGE_FILE_MACHINE_IA64; - StackFrame.AddrPC.Offset = Context.StIIP; - StackFrame.AddrPC.Mode = AddrModeFlat; - StackFrame.AddrFrame.Offset = Context.IntSp; - StackFrame.AddrFrame.Mode = AddrModeFlat; - StackFrame.AddrBStore.Offset= Context.RsBSP; - StackFrame.AddrBStore.Mode = AddrModeFlat; - StackFrame.AddrStack.Offset = Context.IntSp; - StackFrame.AddrStack.Mode = AddrModeFlat; + MachineType = IMAGE_FILE_MACHINE_IA64; + StackFrame.AddrPC.Offset = Context.StIIP; + StackFrame.AddrPC.Mode = AddrModeFlat; + StackFrame.AddrFrame.Offset = Context.IntSp; + StackFrame.AddrFrame.Mode = AddrModeFlat; + StackFrame.AddrBStore.Offset = Context.RsBSP; + StackFrame.AddrBStore.Mode = AddrModeFlat; + StackFrame.AddrStack.Offset = Context.IntSp; + StackFrame.AddrStack.Mode = AddrModeFlat; #else #error "Unsupported platform" #endif - //EnterCriticalSection(&DbgHelpLock); - - QFile logFile(filename); - logFile.open(QIODevice::Append); - QTextStream logStream(&logFile); - - HANDLE hProcess = GetCurrentProcess(); - HANDLE hThread = GetCurrentThread(); - SymInitialize(hProcess, NULL, TRUE); - - DWORD64 dwDisplacement; - - 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; - - IMAGEHLP_MODULE64 mod; - mod.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); - - IMAGEHLP_STACK_FRAME ihsf; - ZeroMemory(&ihsf, sizeof(IMAGEHLP_STACK_FRAME)); - - int i = 0; - while(StackWalk64(MachineType, hProcess, hThread, &StackFrame, &Context, NULL, NULL, NULL, NULL)) { - if(i == 128) - break; - - loadHelpStackFrame(ihsf, StackFrame); - if(StackFrame.AddrPC.Offset != 0) { // Valid frame. - - QString fileName("???"); - if(SymGetModuleInfo64(hProcess, ihsf.InstructionOffset, &mod)) { - fileName = QString(mod.ImageName); - int slashPos = fileName.lastIndexOf('\\'); - if(slashPos != -1) - fileName = fileName.mid(slashPos + 1); - } - QString funcName; - if(SymFromAddr(hProcess, ihsf.InstructionOffset, &dwDisplacement, pSymbol)) { - funcName = QString(pSymbol->Name); - } else { - funcName = QString("0x%1").arg(ihsf.InstructionOffset, 8, 16, QLatin1Char('0')); - } - QStringList params; - SymSetContext(hProcess, &ihsf, NULL); - SymEnumSymbols(hProcess, 0, NULL, EnumSymbolsCB, (PVOID)¶ms); - - QString debugLine = QString("#%1 %2 0x%3 %4(%5)").arg(i, 3, 10) - .arg(fileName, -20) - .arg(ihsf.InstructionOffset, 8, 16, QLatin1Char('0')) - .arg(funcName) - .arg(params.join(", ")); - // qDebug() << qPrintable(debugLine); - logStream << debugLine << '\n'; - i++; - } else { - break; // we're at the end. + //EnterCriticalSection(&DbgHelpLock); + + QFile logFile(filename); + logFile.open(QIODevice::Append); + QTextStream logStream(&logFile); + + HANDLE hProcess = GetCurrentProcess(); + HANDLE hThread = GetCurrentThread(); + SymInitialize(hProcess, NULL, TRUE); + + DWORD64 dwDisplacement; + + 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; + + IMAGEHLP_MODULE64 mod; + mod.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); + + IMAGEHLP_STACK_FRAME ihsf; + ZeroMemory(&ihsf, sizeof(IMAGEHLP_STACK_FRAME)); + + int i = 0; + while (StackWalk64(MachineType, hProcess, hThread, &StackFrame, &Context, NULL, NULL, NULL, NULL)) { + if (i == 128) + break; + + loadHelpStackFrame(ihsf, StackFrame); + if (StackFrame.AddrPC.Offset != 0) { // Valid frame. + QString fileName("???"); + if (SymGetModuleInfo64(hProcess, ihsf.InstructionOffset, &mod)) { + fileName = QString(mod.ImageName); + int slashPos = fileName.lastIndexOf('\\'); + if (slashPos != -1) + fileName = fileName.mid(slashPos + 1); + } + QString funcName; + if (SymFromAddr(hProcess, ihsf.InstructionOffset, &dwDisplacement, pSymbol)) { + funcName = QString(pSymbol->Name); + } + else { + funcName = QString("0x%1").arg(ihsf.InstructionOffset, 8, 16, QLatin1Char('0')); + } + QStringList params; + SymSetContext(hProcess, &ihsf, NULL); + SymEnumSymbols(hProcess, 0, NULL, EnumSymbolsCB, (PVOID)¶ms); + + QString debugLine = QString("#%1 %2 0x%3 %4(%5)").arg(i, 3, 10) + .arg(fileName, -20) + .arg(ihsf.InstructionOffset, 8, 16, QLatin1Char('0')) + .arg(funcName) + .arg(params.join(", ")); + // qDebug() << qPrintable(debugLine); + logStream << debugLine << '\n'; + i++; + } + else { + break; // we're at the end. + } } - } - // qDebug() << "List of linked Modules:"; - logStream << "\n\nList of linked Modules:\n"; - EnumModulesContext modulesContext(hProcess, logStream); - SymEnumerateModules64(hProcess, EnumModulesCB, (PVOID)&modulesContext); + // qDebug() << "List of linked Modules:"; + logStream << "\n\nList of linked Modules:\n"; + EnumModulesContext modulesContext(hProcess, logStream); + SymEnumerateModules64(hProcess, EnumModulesCB, (PVOID)&modulesContext); - logFile.close(); + logFile.close(); } + + #if defined(_M_IX86) && defined(Q_CC_MSVC) #pragma warning(pop) #pragma optimize("g", on)