From ba9f6a3531667d8c8007cec83dbd274f42a496dc Mon Sep 17 00:00:00 2001 From: Nick Tiskov Date: Thu, 27 Nov 2014 21:56:24 +0300 Subject: [PATCH 1/5] Follow project coding style. Issue #2192. --- src/stacktrace_win.h | 352 ++++++++++++++++++++------------------- src/stacktrace_win_dlg.h | 69 ++++---- 2 files changed, 216 insertions(+), 205 deletions(-) diff --git a/src/stacktrace_win.h b/src/stacktrace_win.h index 224d9c91a..c2cf836b8 100644 --- a/src/stacktrace_win.h +++ b/src/stacktrace_win.h @@ -1,22 +1,22 @@ /*************************************************************************** - * Copyright (C) 2005-09 by the Quassel Project * - * 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. * - ***************************************************************************/ +* Copyright (C) 2005-09 by the Quassel Project * +* 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 #include @@ -24,72 +24,77 @@ #include -namespace straceWin{ - void loadHelpStackFrame(IMAGEHLP_STACK_FRAME&, const STACKFRAME64&); - BOOL CALLBACK EnumSymbolsCB(PSYMBOL_INFO, ULONG, PVOID); - BOOL CALLBACK EnumModulesCB(LPCSTR, DWORD64, PVOID); - const QString getBacktrace(); - struct EnumModulesContext; +namespace straceWin +{ + void loadHelpStackFrame(IMAGEHLP_STACK_FRAME&, const STACKFRAME64&); + BOOL CALLBACK EnumSymbolsCB(PSYMBOL_INFO, ULONG, PVOID); + BOOL CALLBACK EnumModulesCB(LPCSTR, DWORD64, PVOID); + const QString getBacktrace(); + struct EnumModulesContext; } -void straceWin::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 straceWin::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 straceWin::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 straceWin::EnumSymbolsCB(PSYMBOL_INFO symInfo, ULONG size, PVOID user) +{ + QStringList* params = (QStringList*)user; + if (symInfo->Flags & SYMFLAG_PARAMETER) + params->append(symInfo->Name); + return TRUE; } -struct straceWin::EnumModulesContext { - HANDLE hProcess; - QTextStream &stream; - EnumModulesContext(HANDLE hProcess, QTextStream &stream) : hProcess(hProcess), stream(stream) {} +struct straceWin::EnumModulesContext +{ + HANDLE hProcess; + QTextStream& stream; + EnumModulesContext(HANDLE hProcess, QTextStream& stream): hProcess(hProcess), stream(stream) {} }; -BOOL CALLBACK straceWin::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 moduleBase = QString("0x%1").arg(BaseOfDll, 8, 16, QLatin1Char('0')); - QString line = QString("%1 %2 Image: %3") - .arg(mod.ModuleName, -14) - .arg(moduleBase, -13) - .arg(mod.LoadedImageName); - context->stream << line << '\n'; - - QString pdbName(mod.LoadedPdbName); - if(!pdbName.isEmpty()) { - QString line2 = QString("%1 %2") - .arg("", 35) - .arg(pdbName); - context->stream << line2 << '\n'; +BOOL CALLBACK straceWin::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 moduleBase = QString("0x%1").arg(BaseOfDll, 8, 16, QLatin1Char('0')); + QString line = QString("%1 %2 Image: %3") + .arg(mod.ModuleName, -14) + .arg(moduleBase, -13) + .arg(mod.LoadedImageName); + context->stream << line << '\n'; + + QString pdbName(mod.LoadedPdbName); + if(!pdbName.isEmpty()) { + QString line2 = QString("%1 %2") + .arg("", 35) + .arg(pdbName); + 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 - #pragma optimize("g", off) - #pragma warning(push) - #pragma warning(disable : 4748) +// 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 -const QString straceWin::getBacktrace() { - DWORD MachineType; - CONTEXT Context; - STACKFRAME64 StackFrame; +const QString straceWin::getBacktrace() +{ + DWORD MachineType; + CONTEXT Context; + STACKFRAME64 StackFrame; #ifdef _M_IX86 ZeroMemory(&Context, sizeof(CONTEXT)); @@ -97,127 +102,128 @@ const QString straceWin::getBacktrace() { #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" +#error "Unsupported platform" #endif - QString log; - QTextStream logStream(&log); - logStream << "```\n"; - - 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 insOffset = QString("0x%1").arg(ihsf.InstructionOffset, 8, 16, QLatin1Char('0')); - QString debugLine = QString("#%1 %2 %3 %4(%5)") - .arg(i, 3, 10) - .arg(fileName, -20) - .arg(insOffset, -11) - .arg(funcName) - .arg(params.join(", ")); - logStream << debugLine << '\n'; - i++; - } else { - break; // we're at the end. + QString log; + QTextStream logStream(&log); + logStream << "```\n"; + + 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 insOffset = QString("0x%1").arg(ihsf.InstructionOffset, 8, 16, QLatin1Char('0')); + QString debugLine = QString("#%1 %2 %3 %4(%5)") + .arg(i, 3, 10) + .arg(fileName, -20) + .arg(insOffset, -11) + .arg(funcName) + .arg(params.join(", ")); + logStream << debugLine << '\n'; + i++; + } + else { + break; // we're at the end. + } } - } - logStream << "\n\nList of linked Modules:\n"; - EnumModulesContext modulesContext(hProcess, logStream); - SymEnumerateModules64(hProcess, EnumModulesCB, (PVOID)&modulesContext); - logStream << "```"; - return log; + logStream << "\n\nList of linked Modules:\n"; + EnumModulesContext modulesContext(hProcess, logStream); + SymEnumerateModules64(hProcess, EnumModulesCB, (PVOID)&modulesContext); + logStream << "```"; + return log; } #if defined(_M_IX86) && defined(Q_CC_MSVC) - #pragma warning(pop) - #pragma optimize("g", on) +#pragma warning(pop) +#pragma optimize("g", on) #endif diff --git a/src/stacktrace_win_dlg.h b/src/stacktrace_win_dlg.h index f54060950..0040c7da5 100644 --- a/src/stacktrace_win_dlg.h +++ b/src/stacktrace_win_dlg.h @@ -7,43 +7,48 @@ #include "libtorrent/version.hpp" #include "ui_stacktrace_win_dlg.h" -class StraceDlg : public QDialog, private Ui::errorDialog { - Q_OBJECT +class StraceDlg: public QDialog, private Ui::errorDialog +{ + Q_OBJECT public: - StraceDlg(QWidget *parent = 0): QDialog(parent) { - setupUi(this); - } + StraceDlg(QWidget* parent = 0): QDialog(parent) + { + setupUi(this); + } - ~StraceDlg() {} + ~StraceDlg() + { + } - void setStacktraceString(const QString& trace) { - QString htmlStr; - QTextStream outStream(&htmlStr); - outStream << "

" << - "qBittorrent has crashed" << - "

" << - "" << - "

" << - "Please report a bug at " << - "http://bugs.qbittorrent.org" << - " and provide the following backtrace." << - "

" << - "
" << - "


" << - "

qBittorrent version: " << VERSION << - "
Libtorrent version: " << LIBTORRENT_VERSION << - "
Qt version: " << QT_VERSION_STR << - "
Boost version: " << QString::number(BOOST_VERSION / 100000) << '.' << - QString::number((BOOST_VERSION / 100) % 1000) << '.' << - QString::number(BOOST_VERSION % 100) << "


" - "
" <<
-                 trace <<
-                 "
" << - "



"; + void setStacktraceString(const QString& trace) + { + QString htmlStr; + QTextStream outStream(&htmlStr); + outStream << "

" << + "qBittorrent has crashed" << + "

" << + "" << + "

" << + "Please report a bug at " << + "http://bugs.qbittorrent.org" << + " and provide the following backtrace." << + "

" << + "
" << + "


" << + "

qBittorrent version: " << VERSION << + "
Libtorrent version: " << LIBTORRENT_VERSION << + "
Qt version: " << QT_VERSION_STR << + "
Boost version: " << QString::number(BOOST_VERSION / 100000) << '.' << + QString::number((BOOST_VERSION / 100) % 1000) << '.' << + QString::number(BOOST_VERSION % 100) << "


" + "
" <<
+            trace <<
+            "
" << + "



"; - errorText->setHtml(htmlStr); - } + errorText->setHtml(htmlStr); + } }; #endif From cb60519c441a5527a56fbe40e63eef681978cf87 Mon Sep 17 00:00:00 2001 From: Nick Tiskov Date: Thu, 27 Nov 2014 22:08:16 +0300 Subject: [PATCH 2/5] Fix backtrace generation on Mingw: to resolve local functions we need to export them --- winconf-mingw.pri | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/winconf-mingw.pri b/winconf-mingw.pri index 95880cf69..6a834d296 100644 --- a/winconf-mingw.pri +++ b/winconf-mingw.pri @@ -4,10 +4,9 @@ strace_win:{ QMAKE_CXXFLAGS_RELEASE += -fno-omit-frame-pointer QMAKE_CXXFLAGS_DEBUG += -fno-omit-frame-pointer } - release:{ - #QMAKE_CXXFLAGS_RELEASE += -g - #QMAKE_LFLAGS_RELEASE -= -Wl,-s - } + + QMAKE_LFLAGS += -Wl,--export-all-symbols + LIBS += libdbghelp } From 2dd3d1fb2257d7580d97ee94d8e69d14e351f204 Mon Sep 17 00:00:00 2001 From: Nick Tiskov Date: Thu, 27 Nov 2014 22:23:15 +0300 Subject: [PATCH 3/5] Fix indentation for long addresses and filenames --- src/stacktrace_win.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/stacktrace_win.h b/src/stacktrace_win.h index c2cf836b8..56de8d6ef 100644 --- a/src/stacktrace_win.h +++ b/src/stacktrace_win.h @@ -62,9 +62,9 @@ BOOL CALLBACK straceWin::EnumModulesCB(LPCSTR ModuleName, DWORD64 BaseOfDll, PVO EnumModulesContext* context = (EnumModulesContext*)UserContext; mod.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); if(SymGetModuleInfo64(context->hProcess, BaseOfDll, &mod)) { - QString moduleBase = QString("0x%1").arg(BaseOfDll, 8, 16, QLatin1Char('0')); + QString moduleBase = QString("0x%1").arg(BaseOfDll, 16, 16, QLatin1Char('0')); QString line = QString("%1 %2 Image: %3") - .arg(mod.ModuleName, -14) + .arg(mod.ModuleName, -25) .arg(moduleBase, -13) .arg(mod.LoadedImageName); context->stream << line << '\n'; @@ -202,7 +202,7 @@ const QString straceWin::getBacktrace() SymSetContext(hProcess, &ihsf, NULL); SymEnumSymbols(hProcess, 0, NULL, EnumSymbolsCB, (PVOID)¶ms); - QString insOffset = QString("0x%1").arg(ihsf.InstructionOffset, 8, 16, QLatin1Char('0')); + QString insOffset = QString("0x%1").arg(ihsf.InstructionOffset, 16, 16, QLatin1Char('0')); QString debugLine = QString("#%1 %2 %3 %4(%5)") .arg(i, 3, 10) .arg(fileName, -20) From 6bab65e5b43b82d3ad63ca1a8e755e1b62b0d19e Mon Sep 17 00:00:00 2001 From: Nick Tiskov Date: Fri, 28 Nov 2014 01:18:34 +0300 Subject: [PATCH 4/5] Produce demangled backtraces under MinGW --- src/stacktrace_win.h | 47 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/src/stacktrace_win.h b/src/stacktrace_win.h index 56de8d6ef..8d1eced49 100644 --- a/src/stacktrace_win.h +++ b/src/stacktrace_win.h @@ -23,6 +23,9 @@ #include #include +#ifdef __MINGW32__ +#include +#endif namespace straceWin { @@ -31,7 +34,26 @@ namespace straceWin BOOL CALLBACK EnumModulesCB(LPCSTR, DWORD64, PVOID); const QString getBacktrace(); struct EnumModulesContext; + // Also works for MinGW64 +#ifdef __MINGW32__ + void demangle(QString& str); +#endif +} + +#ifdef __MINGW32__ +void straceWin::demangle(QString& str) +{ + char const* inStr = qPrintable("_" + str); // Really need that underline or demangling will fail + int status = 0; + size_t outSz = 0; + char* demangled_name = abi::__cxa_demangle(inStr, 0, &outSz, &status); + if (status == 0) { + str = QString::fromLocal8Bit(demangled_name); + if (outSz > 0) + free(demangled_name); + } } +#endif void straceWin::loadHelpStackFrame(IMAGEHLP_STACK_FRAME& ihsf, const STACKFRAME64& stackFrame) { @@ -42,6 +64,7 @@ void straceWin::loadHelpStackFrame(IMAGEHLP_STACK_FRAME& ihsf, const STACKFRAME6 BOOL CALLBACK straceWin::EnumSymbolsCB(PSYMBOL_INFO symInfo, ULONG size, PVOID user) { + Q_UNUSED(size) QStringList* params = (QStringList*)user; if (symInfo->Flags & SYMFLAG_PARAMETER) params->append(symInfo->Name); @@ -58,6 +81,7 @@ struct straceWin::EnumModulesContext BOOL CALLBACK straceWin::EnumModulesCB(LPCSTR ModuleName, DWORD64 BaseOfDll, PVOID UserContext) { + Q_UNUSED(ModuleName) IMAGEHLP_MODULE64 mod; EnumModulesContext* context = (EnumModulesContext*)UserContext; mod.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); @@ -194,21 +218,36 @@ const QString straceWin::getBacktrace() fileName = fileName.mid(slashPos + 1); } QString funcName; - if(SymFromAddr(hProcess, ihsf.InstructionOffset, &dwDisplacement, pSymbol)) + if(SymFromAddr(hProcess, ihsf.InstructionOffset, &dwDisplacement, pSymbol)) { funcName = QString(pSymbol->Name); - else +#ifdef __MINGW32__ + demangle(funcName); +#endif + } + else { funcName = QString("0x%1").arg(ihsf.InstructionOffset, 8, 16, QLatin1Char('0')); - QStringList params; + } SymSetContext(hProcess, &ihsf, NULL); +#ifndef __MINGW32__ + QStringList params; SymEnumSymbols(hProcess, 0, NULL, EnumSymbolsCB, (PVOID)¶ms); +#endif QString insOffset = QString("0x%1").arg(ihsf.InstructionOffset, 16, 16, QLatin1Char('0')); - QString debugLine = QString("#%1 %2 %3 %4(%5)") + QString formatLine = "#%1 %2 %3 %4"; +#ifndef __MINGW32__ + formatLine += "(%5)"; +#endif + QString debugLine = formatLine .arg(i, 3, 10) .arg(fileName, -20) .arg(insOffset, -11) .arg(funcName) +#ifndef __MINGW32__ .arg(params.join(", ")); +#else + ; +#endif logStream << debugLine << '\n'; i++; } From 2df2b6f4eb400c91968d2ef424c429ce0f087fc9 Mon Sep 17 00:00:00 2001 From: Nick Tiskov Date: Fri, 28 Nov 2014 16:40:08 +0300 Subject: [PATCH 5/5] Always disable ASLR for debug builds - otherwise debugging will fail --- winconf-mingw.pri | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/winconf-mingw.pri b/winconf-mingw.pri index 6a834d296..91309cfb7 100644 --- a/winconf-mingw.pri +++ b/winconf-mingw.pri @@ -10,6 +10,11 @@ strace_win:{ LIBS += libdbghelp } +CONFIG(debug, debug|release) { + # Make sure binary is not relocatable, otherwise debugging will fail + QMAKE_LFLAGS -= -Wl,--dynamicbase +} + RC_FILE = qbittorrent_mingw.rc #You need to link with libtorrent > 0.15.5 (or svn) and you must