X Tutup
#include "debugger.h" #if __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1 || defined(Q_OS_MAC) # include #endif #if defined(Q_CC_GNU) # include #endif #include #include using namespace Utils; /*! * \class Utils::Debugger utils/debugger.h * \brief Application self-debugging support */ //! Constructs human readable backtrace. QString Debugger::backtrace() { static const QString ERR_RETVAL = ""; #if (__GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1 || defined(Q_OS_MAC)) && defined(Q_CC_GNU) static const int MAX_FRAMES = 256; void *addresses[MAX_FRAMES]; const int size = ::backtrace(addresses, MAX_FRAMES); char **const symbols = backtrace_symbols(addresses, size); if (symbols == 0) { qWarning("%s: backtrace_symbols failed", Q_FUNC_INFO); return ERR_RETVAL; } QString retv; #if defined(Q_OS_MAC) QRegExp regexp("^[0-9]+\\s+(\\S+)\\s+(0x[0-9a-f]+) ([^+]+) \\+ ([0-9]+)$"); #else QRegExp regexp("^(.*)\\(([^()+]*)\\+(0x[0-9a-f]+)?\\) (\\[0x[0-9a-f]+\\])$"); #endif for (int i = 1; i < size; ++i) { if (regexp.exactMatch(symbols[i])) { #if defined(Q_OS_MAC) const QString source = QFileInfo(regexp.cap(1)).fileName(); const QString mangledSymbol = regexp.cap(3); const QString offset = regexp.cap(4); const QString frame = regexp.cap(2); #else const QString source = QFileInfo(regexp.cap(1)).fileName(); const QString mangledSymbol = regexp.cap(2); const QString offset = regexp.cap(3); const QString frame = regexp.cap(4); #endif char *const demangledSymbol = abi::__cxa_demangle(qPrintable(mangledSymbol), 0, 0, 0); const QString symbol = demangledSymbol != 0 ? demangledSymbol : (!mangledSymbol.isEmpty() ? mangledSymbol : QString("")); retv.append(QString("%1 %2+%3 in %4\n") .arg(frame) .arg(symbol) .arg(offset) .arg(source)); free(demangledSymbol); } else { retv.append(QString("<%1>\n").arg(symbols[i])); } } free(symbols); return retv; #else qWarning("%s: Platform unsupported", Q_FUNC_INFO); return ERR_RETVAL; #endif }
X Tutup