forked from qt-creator/qt-creator
Utils: print assert backtrace on windows
Change-Id: Ifd9753b22641547c16fb6843dc7a3cf5f5b7c86e Reviewed-by: Christian Stenger <christian.stenger@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: David Schulz <david.schulz@qt.io> Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
@@ -217,6 +217,14 @@ extend_qtc_library(Utils
|
|||||||
mimeutils.cpp
|
mimeutils.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (MSVC)
|
||||||
|
find_library(DbgHelpLib dbghelp)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
extend_qtc_library(Utils CONDITION MSVC
|
||||||
|
DEPENDS ${DbgHelpLib}
|
||||||
|
)
|
||||||
|
|
||||||
extend_qtc_library(Utils CONDITION WIN32
|
extend_qtc_library(Utils CONDITION WIN32
|
||||||
SOURCES
|
SOURCES
|
||||||
touchbar/touchbar.cpp
|
touchbar/touchbar.cpp
|
||||||
|
@@ -5,11 +5,20 @@
|
|||||||
|
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QMutex>
|
||||||
|
|
||||||
#if defined(Q_OS_UNIX)
|
#if defined(Q_OS_UNIX)
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <execinfo.h>
|
#include <execinfo.h>
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#ifdef QTCREATOR_PCH_H
|
||||||
|
#define CALLBACK WINAPI
|
||||||
|
#define OUT
|
||||||
|
#define IN
|
||||||
|
#endif
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <DbgHelp.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
@@ -26,6 +35,74 @@ void dumpBacktrace(int maxdepth)
|
|||||||
for (int i = 0; i < size; ++i)
|
for (int i = 0; i < size; ++i)
|
||||||
qDebug() << "0x" + QByteArray::number(quintptr(bt[i]), 16) << lines[i];
|
qDebug() << "0x" + QByteArray::number(quintptr(bt[i]), 16) << lines[i];
|
||||||
free(lines);
|
free(lines);
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
DWORD machineType;
|
||||||
|
#if defined(Q_OS_WIN64)
|
||||||
|
machineType = IMAGE_FILE_MACHINE_AMD64;
|
||||||
|
#else
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
static QMutex mutex;
|
||||||
|
mutex.lock();
|
||||||
|
HANDLE process = GetCurrentProcess();
|
||||||
|
HANDLE thread = GetCurrentThread();
|
||||||
|
CONTEXT ctx;
|
||||||
|
RtlCaptureContext(&ctx);
|
||||||
|
STACKFRAME64 frame;
|
||||||
|
memset(&frame, 0, sizeof(STACKFRAME64));
|
||||||
|
#if defined(Q_OS_WIN64)
|
||||||
|
frame.AddrPC.Offset = ctx.Rip;
|
||||||
|
frame.AddrPC.Mode = AddrModeFlat;
|
||||||
|
frame.AddrStack.Offset = ctx.Rsp;
|
||||||
|
frame.AddrStack.Mode = AddrModeFlat;
|
||||||
|
frame.AddrFrame.Offset = ctx.Rbp;
|
||||||
|
frame.AddrFrame.Mode = AddrModeFlat;
|
||||||
|
#endif
|
||||||
|
int depth = 0;
|
||||||
|
|
||||||
|
static bool symbolsInitialized = false;
|
||||||
|
if (!symbolsInitialized) {
|
||||||
|
SymInitialize(process, NULL, TRUE);
|
||||||
|
SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
|
||||||
|
symbolsInitialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (StackWalk64(machineType,
|
||||||
|
process,
|
||||||
|
thread,
|
||||||
|
&frame,
|
||||||
|
&ctx,
|
||||||
|
NULL,
|
||||||
|
&SymFunctionTableAccess64,
|
||||||
|
&SymGetModuleBase64,
|
||||||
|
NULL)) {
|
||||||
|
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
|
||||||
|
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
|
||||||
|
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||||
|
pSymbol->MaxNameLen = MAX_SYM_NAME;
|
||||||
|
|
||||||
|
DWORD64 displacement = 0;
|
||||||
|
if (!SymFromAddr(process, frame.AddrPC.Offset, &displacement, pSymbol))
|
||||||
|
break;
|
||||||
|
|
||||||
|
DWORD symDisplacement = 0;
|
||||||
|
IMAGEHLP_LINE64 lineInfo;
|
||||||
|
SymSetOptions(SYMOPT_LOAD_LINES);
|
||||||
|
|
||||||
|
QString out = QString("%1: 0x%2 at %3")
|
||||||
|
.arg(depth)
|
||||||
|
.arg(QString::number(pSymbol->Address, 16))
|
||||||
|
.arg(QString::fromLatin1(&pSymbol->Name[0], pSymbol->NameLen));
|
||||||
|
if (SymGetLineFromAddr64(process, frame.AddrPC.Offset, &symDisplacement, &lineInfo)) {
|
||||||
|
out.append(QString(" at %3:%4")
|
||||||
|
.arg(QString::fromLatin1(lineInfo.FileName),
|
||||||
|
QString::number(lineInfo.LineNumber)));
|
||||||
|
}
|
||||||
|
qDebug() << out;
|
||||||
|
if (++depth == maxdepth)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mutex.unlock();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -17,6 +17,8 @@ Project {
|
|||||||
libs.push("user32", "iphlpapi", "ws2_32", "shell32", "ole32");
|
libs.push("user32", "iphlpapi", "ws2_32", "shell32", "ole32");
|
||||||
if (qbs.toolchainType === "mingw")
|
if (qbs.toolchainType === "mingw")
|
||||||
libs.push("uuid");
|
libs.push("uuid");
|
||||||
|
else if (qbs.toolchainType === "msvc")
|
||||||
|
libs.push("dbghelp");
|
||||||
} else if (qbs.targetOS.contains("unix")) {
|
} else if (qbs.targetOS.contains("unix")) {
|
||||||
if (!qbs.targetOS.contains("macos"))
|
if (!qbs.targetOS.contains("macos"))
|
||||||
libs.push("X11");
|
libs.push("X11");
|
||||||
|
@@ -22,3 +22,11 @@ add_qtc_executable(qtcreator_processlauncher
|
|||||||
${UTILSDIR}/singleton.cpp
|
${UTILSDIR}/singleton.cpp
|
||||||
${UTILSDIR}/singleton.h
|
${UTILSDIR}/singleton.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (MSVC)
|
||||||
|
find_library(DbgHelpLib dbghelp)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
extend_qtc_executable(qtcreator_processlauncher CONDITION MSVC
|
||||||
|
DEPENDS ${DbgHelpLib}
|
||||||
|
)
|
||||||
|
@@ -11,7 +11,9 @@ QtcTool {
|
|||||||
|
|
||||||
Properties {
|
Properties {
|
||||||
condition: qbs.targetOS.contains("windows")
|
condition: qbs.targetOS.contains("windows")
|
||||||
cpp.dynamicLibraries: "user32"
|
cpp.dynamicLibraries: {
|
||||||
|
return qbs.toolchainType === "msvc" ? ["user32", "dbghelp"] : ["user32"];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
files: [
|
files: [
|
||||||
|
@@ -90,6 +90,13 @@ extend_qtc_library(sdktoolLib CONDITION APPLE
|
|||||||
${FWFoundation}
|
${FWFoundation}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (MSVC)
|
||||||
|
find_library(DbgHelpLib dbghelp)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
extend_qtc_library(sdktoolLib CONDITION MSVC
|
||||||
|
DEPENDS ${DbgHelpLib}
|
||||||
|
)
|
||||||
extend_qtc_library(sdktoolLib CONDITION WIN32
|
extend_qtc_library(sdktoolLib CONDITION WIN32
|
||||||
PUBLIC_DEPENDS
|
PUBLIC_DEPENDS
|
||||||
user32 iphlpapi ws2_32 shell32
|
user32 iphlpapi ws2_32 shell32
|
||||||
|
@@ -24,8 +24,12 @@ QtcLibrary {
|
|||||||
return defines;
|
return defines;
|
||||||
}
|
}
|
||||||
cpp.dynamicLibraries: {
|
cpp.dynamicLibraries: {
|
||||||
|
var libs = [];
|
||||||
if (qbs.targetOS.contains("windows"))
|
if (qbs.targetOS.contains("windows"))
|
||||||
return ["user32", "shell32"]
|
libs.push("user32", "shell32");
|
||||||
|
if (qbs.toolchainType === "msvc")
|
||||||
|
libs.push("dbghelp");
|
||||||
|
return libs;
|
||||||
}
|
}
|
||||||
Properties {
|
Properties {
|
||||||
condition: qbs.targetOS.contains("macos")
|
condition: qbs.targetOS.contains("macos")
|
||||||
|
Reference in New Issue
Block a user