| 1600 | #include <unistd.h> |
| 1601 | #include <execinfo.h> |
| 1602 | #include <cxxabi.h> |
| 1603 | |
| 1604 | static QString maybeDemangledName(char *name) |
| 1605 | { |
| 1606 | const int len = strlen(name); |
| 1607 | QByteArray in = QByteArray::fromRawData(name, len); |
| 1608 | #ifdef Q_OS_MAC |
| 1609 | const int mangledNameStart = in.indexOf(" _"), startOffset = 1; |
| 1610 | #elif defined(__FreeBSD__) |
| 1611 | const int mangledNameStart = in.indexOf(" <_"), startOffset = 2; |
| 1612 | #elif defined(__sun) && defined(__SVR4) |
| 1613 | const int mangledNameStart = in.indexOf("'"), startOffset = 0; |
| 1614 | #else |
| 1615 | const int mangledNameStart = in.indexOf("(_"), startOffset = 1; |
| 1616 | #endif |
| 1617 | if (mangledNameStart >= 0) { |
| 1618 | int mangledNameEnd = in.indexOf('+', mangledNameStart + 2); |
| 1619 | // check for and suppress trailing whitespace: |
| 1620 | if (mangledNameEnd > 1 && isspace(name[mangledNameEnd-1])) { |
| 1621 | mangledNameEnd -= 1; |
| 1622 | while (mangledNameEnd > 1 && isspace(name[mangledNameEnd-1])) { |
| 1623 | --mangledNameEnd; |
| 1624 | } |
| 1625 | } |
| 1626 | if (mangledNameEnd >= 0) { |
| 1627 | int status; |
| 1628 | // if we forget about this line and the one that undoes its effect we don't change the |
| 1629 | // internal data of the QByteArray::fromRawData() ;) |
| 1630 | const char endChar = name[mangledNameEnd]; |
| 1631 | name[mangledNameEnd] = 0; |
| 1632 | char *demangled = abi::__cxa_demangle(name + mangledNameStart + startOffset, 0, 0, &status); |
| 1633 | name[mangledNameEnd] = endChar; |
| 1634 | if (demangled) { |
| 1635 | QString ret = QString::fromLatin1(name, mangledNameStart + startOffset) + |
| 1636 | QString::fromLatin1(demangled) + |
| 1637 | QString::fromLatin1(name + mangledNameEnd, len - mangledNameEnd); |
| 1638 | free(demangled); |
| 1639 | return ret; |
| 1640 | } |
| 1641 | } |
| 1642 | } |
| 1643 | return QString::fromLatin1(name); |
| 1644 | } |
| 1645 | |
| 1646 | QString kRealBacktrace(int levels) |
| 1647 | { |
| 1648 | QString s; |
| 1649 | void* trace[256]; |
| 1650 | int n = backtrace(trace, 256); |
| 1651 | if (!n) |
| 1652 | return s; |
| 1653 | char** strings = backtrace_symbols (trace, n); |
| 1654 | |
| 1655 | if ( levels != -1 ) |
| 1656 | n = qMin( n, levels ); |
| 1657 | s = QLatin1String("[\n"); |
| 1658 | |
| 1659 | for (int i = 0; i < n; ++i) |
| 1660 | s += QString::number(i) + QLatin1String(": ") + |
| 1661 | maybeDemangledName(strings[i]) + QLatin1Char('\n'); |
| 1662 | s += QLatin1String("]\n"); |
| 1663 | if (strings) |
| 1664 | free (strings); |
| 1665 | return s; |
| 1666 | } |
| 1667 | |
| 1668 | |