From: Marcus Eggenberger Date: Mon, 10 Nov 2008 23:25:22 +0000 (+0100) Subject: this should make quassel compile on vs2005 again X-Git-Tag: 0.3.1~49 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=02a1bb313c5b39a8ecc48cbd88ebc99be903dc35;ds=sidebyside this should make quassel compile on vs2005 again --- diff --git a/src/common/logbacktrace_win.cpp b/src/common/logbacktrace_win.cpp old mode 100755 new mode 100644 index abcab480..779e5cbe --- a/src/common/logbacktrace_win.cpp +++ b/src/common/logbacktrace_win.cpp @@ -1,203 +1,207 @@ -/*************************************************************************** - * Copyright (C) 2005-08 by the Quassel IRC Team * - * devel@quassel-irc.org * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) version 3. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - -#include "quassel.h" - -#include -#include -#include - -// #include -#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; -} - -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) {} -}; - -BOOL CALLBACK EnumModulesCB(PCTSTR 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; -} - -#ifdef _M_IX86 - // Disable global optimization and ignore /GS waning caused by - // inline assembly. - #pragma optimize("g", off) - #pragma warning(push) - #pragma warning(disable : 4748) -#endif -void Quassel::logBacktrace(const QString &filename) { - DWORD MachineType; - CONTEXT Context; - STACKFRAME64 StackFrame; - -#ifdef _M_IX86 - ZeroMemory(&Context, sizeof(CONTEXT)); - Context.ContextFlags = CONTEXT_CONTROL; - __asm { - Label: - mov [Context.Ebp], ebp; - mov [Context.Esp], esp; - mov eax, [Label]; - mov [Context.Eip], eax; - } -#else - RtlCaptureContext(&Context); -#endif - - 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; -#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; -#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; -#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. - } - } - - // qDebug() << "List of linked Modules:"; - logStream << "\n\nList of linked Modules:\n"; - EnumModulesContext modulesContext(hProcess, logStream); - SymEnumerateModules64(hProcess, EnumModulesCB, (PVOID)&modulesContext); - - logFile.close(); -} -#ifdef _M_IX86 - #pragma warning(pop) - #pragma optimize("g", on) -#endif +/*************************************************************************** + * Copyright (C) 2005-08 by the Quassel IRC Team * + * devel@quassel-irc.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) version 3. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "quassel.h" + +#include +#include +#include + +// #include +#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; +} + +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) {} +}; + +#if _MSC_VER >= 1500 +BOOL CALLBACK EnumModulesCB(PCTSTR ModuleName, DWORD64 BaseOfDll, PVOID UserContext) { +#else +BOOL CALLBACK EnumModulesCB(PSTR ModuleName, DWORD64 BaseOfDll, PVOID UserContext) { +#endif + 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; +} + +#ifdef _M_IX86 + // Disable global optimization and ignore /GS waning caused by + // inline assembly. + #pragma optimize("g", off) + #pragma warning(push) + #pragma warning(disable : 4748) +#endif +void Quassel::logBacktrace(const QString &filename) { + DWORD MachineType; + CONTEXT Context; + STACKFRAME64 StackFrame; + +#ifdef _M_IX86 + ZeroMemory(&Context, sizeof(CONTEXT)); + Context.ContextFlags = CONTEXT_CONTROL; + __asm { + Label: + mov [Context.Ebp], ebp; + mov [Context.Esp], esp; + mov eax, [Label]; + mov [Context.Eip], eax; + } +#else + RtlCaptureContext(&Context); +#endif + + 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; +#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; +#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; +#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. + } + } + + // qDebug() << "List of linked Modules:"; + logStream << "\n\nList of linked Modules:\n"; + EnumModulesContext modulesContext(hProcess, logStream); + SymEnumerateModules64(hProcess, EnumModulesCB, (PVOID)&modulesContext); + + logFile.close(); +} +#ifdef _M_IX86 + #pragma warning(pop) + #pragma optimize("g", on) +#endif