| | 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 | |