11 #include <QLatin1String>
12 #include <QMutexLocker>
13 #include <QStringBuilder>
15 #if defined(Q_CC_MSVC)
18 # pragma warning(push)
19 # pragma warning(disable : 4091)
23 #elif defined(Q_OS_WIN) && defined(Q_CC_GNU)
26 #elif defined(Q_CC_GNU)
28 # include <execinfo.h>
39 QStringList
getStackTrace() {
return {
"No stack trace with release build" }; }
42 #if defined(Q_OS_WIN32)
46 QMutexLocker lock(&mutex);
48 static std::once_flag flag;
49 std::call_once(flag, [] {
50 SymInitialize(GetCurrentProcess(),
nullptr,
true);
51 std::atexit([] { SymCleanup(GetCurrentProcess()); });
54 auto process = GetCurrentProcess();
55 SymRefreshModuleList(process);
57 using stackarray = std::array<void *, 100>;
59 auto frames = CaptureStackBackTrace(1,
static_cast<DWORD>(stack.size()), stack.data(),
nullptr);
64 std::array<char, 256> name;
66 symbol.info.MaxNameLen =
static_cast<ULONG
>(symbol.name.size() - 1);
67 symbol.info.SizeOfStruct =
sizeof(symbol.info);
70 for (stackarray::size_type i = 0; i < frames; ++i)
72 DWORD displacement = 0;
74 line.SizeOfStruct =
sizeof(line);
75 SymFromAddr(process,
reinterpret_cast<quintptr
>(stack[i]),
nullptr, &symbol.info);
76 SymGetLineFromAddr64(process,
reinterpret_cast<quintptr
>(stack[i]), &displacement, &line);
78 result.push_back(QLatin1String(symbol.info.Name) % u
" line " % QString::number(line.LineNumber));
82 #elif defined(Q_CC_GNU)
85 std::array<void *, 100> stack;
86 auto frames = backtrace(stack.data(), stack.size());
87 auto *symbols = backtrace_symbols(stack.data(), frames);
90 char *demangled =
nullptr;
92 for (
int i = 0; i < frames; ++i)
95 auto *basename = std::strrchr(symbols[i],
'/');
96 if (!basename) {
continue; }
98 auto *symbol = std::strchr(basename,
'(');
99 if (!symbol) {
continue; }
100 auto *basenameEnd = symbol++;
101 auto *
end = std::strrchr(symbol,
')');
102 if (!
end) {
continue; }
103 auto *offset = std::strrchr(symbol,
'+');
104 auto *symbolEnd = offset ? offset++ :
end;
106 auto *temp = demangled;
109 abi::__cxa_demangle(QByteArray(symbol, symbolEnd - symbol).constData(), demangled, &size,
nullptr);
113 result.push_back(QLatin1String(demangled) % u
' ' % u
'(' %
114 QLatin1String(basename, basenameEnd - basename) % u
' ' %
115 QLatin1String(symbol,
end - symbol) % u
')');
119 result.push_back(u
'(' % QLatin1String(basename, basenameEnd - basename) % u
' ' %
120 QLatin1String(symbol,
end - symbol) % u
')');
Free functions in swift::misc.
T::const_iterator end(const LockFreeReader< T > &reader)
Non-member begin() and end() for so LockFree containers can be used in ranged for loops.
QStringList getStackTraceAlways()
Returns a stack trace of the current thread of execution as a list of function names.
QStringList getStackTrace()
Returns a stack trace of the current thread of execution as a list of function names.
unsigned long DWORD
Fake Windows DWORD.