Browse Source

Merge pull request #2214 from Gelmir/trace

Fix backtrace functionality under MinGW
adaptive-webui-19844
sledgehammer999 10 years ago
parent
commit
6c0b74b94b
  1. 75
      src/stacktrace_win.h
  2. 13
      src/stacktrace_win_dlg.h
  3. 12
      winconf-mingw.pri

75
src/stacktrace_win.h

@ -23,44 +23,72 @@ @@ -23,44 +23,72 @@
#include <stdio.h>
#include <QTextStream>
#ifdef __MINGW32__
#include <cxxabi.h>
#endif
namespace straceWin{
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;
// Also works for MinGW64
#ifdef __MINGW32__
void demangle(QString& str);
#endif
}
void straceWin::loadHelpStackFrame(IMAGEHLP_STACK_FRAME &ihsf, const STACKFRAME64 &stackFrame) {
#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)
{
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) {
BOOL CALLBACK straceWin::EnumSymbolsCB(PSYMBOL_INFO symInfo, ULONG size, PVOID user)
{
Q_UNUSED(size)
QStringList* params = (QStringList*)user;
if(symInfo->Flags & SYMFLAG_PARAMETER) {
if (symInfo->Flags & SYMFLAG_PARAMETER)
params->append(symInfo->Name);
}
return TRUE;
}
struct straceWin::EnumModulesContext {
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) {
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);
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';
@ -86,7 +114,8 @@ BOOL CALLBACK straceWin::EnumModulesCB(LPCSTR ModuleName, DWORD64 BaseOfDll, PVO @@ -86,7 +114,8 @@ BOOL CALLBACK straceWin::EnumModulesCB(LPCSTR ModuleName, DWORD64 BaseOfDll, PVO
#pragma warning(push)
#pragma warning(disable : 4748)
#endif
const QString straceWin::getBacktrace() {
const QString straceWin::getBacktrace()
{
DWORD MachineType;
CONTEXT Context;
STACKFRAME64 StackFrame;
@ -173,6 +202,7 @@ const QString straceWin::getBacktrace() { @@ -173,6 +202,7 @@ const QString straceWin::getBacktrace() {
ZeroMemory(&ihsf, sizeof(IMAGEHLP_STACK_FRAME));
int i = 0;
while(StackWalk64(MachineType, hProcess, hThread, &StackFrame, &Context, NULL, NULL, NULL, NULL)) {
if(i == 128)
break;
@ -190,23 +220,38 @@ const QString straceWin::getBacktrace() { @@ -190,23 +220,38 @@ const QString straceWin::getBacktrace() {
QString funcName;
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)&params);
#endif
QString insOffset = QString("0x%1").arg(ihsf.InstructionOffset, 8, 16, QLatin1Char('0'));
QString debugLine = QString("#%1 %2 %3 %4(%5)")
QString insOffset = QString("0x%1").arg(ihsf.InstructionOffset, 16, 16, QLatin1Char('0'));
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++;
} else {
}
else {
break; // we're at the end.
}
}

13
src/stacktrace_win_dlg.h

@ -7,17 +7,22 @@ @@ -7,17 +7,22 @@
#include "libtorrent/version.hpp"
#include "ui_stacktrace_win_dlg.h"
class StraceDlg : public QDialog, private Ui::errorDialog {
class StraceDlg: public QDialog, private Ui::errorDialog
{
Q_OBJECT
public:
StraceDlg(QWidget *parent = 0): QDialog(parent) {
StraceDlg(QWidget* parent = 0): QDialog(parent)
{
setupUi(this);
}
~StraceDlg() {}
~StraceDlg()
{
}
void setStacktraceString(const QString& trace) {
void setStacktraceString(const QString& trace)
{
QString htmlStr;
QTextStream outStream(&htmlStr);
outStream << "<p align=center><b><font size=7 color=red>" <<

12
winconf-mingw.pri

@ -4,13 +4,17 @@ strace_win:{ @@ -4,13 +4,17 @@ 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
}
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

Loading…
Cancel
Save