Logs the stack trace using the libunwind call. * The eip argument is unused as libunwind only gets local context. * The uplevel argument indicates how many of the calling functions to skip. */
| 1667 | * The uplevel argument indicates how many of the calling functions to skip. |
| 1668 | */ |
| 1669 | void logStackTrace(void * eip, int uplevel) { |
| 1670 | (void)eip;//UNUSED |
| 1671 | const char *msg; |
| 1672 | int fd = openDirectLogFiledes(); |
| 1673 | |
| 1674 | if (fd == -1) return; /* If we can't log there is anything to do. */ |
| 1675 | |
| 1676 | msg = "\n------ STACK TRACE ------\n"; |
| 1677 | if (write(fd,msg,strlen(msg)) == -1) {/* Avoid warning. */}; |
| 1678 | unw_cursor_t cursor; |
| 1679 | unw_context_t context; |
| 1680 | |
| 1681 | unw_getcontext(&context); |
| 1682 | unw_init_local(&cursor, &context); |
| 1683 | |
| 1684 | /* Write symbols to log file */ |
| 1685 | msg = "\nBacktrace:\n"; |
| 1686 | if (write(fd,msg,strlen(msg)) == -1) {/* Avoid warning. */}; |
| 1687 | |
| 1688 | for (int i = 0; i < uplevel; i++) { |
| 1689 | unw_step(&cursor); |
| 1690 | } |
| 1691 | |
| 1692 | while ( unw_step(&cursor) ) { |
| 1693 | unw_word_t ip, sp, off; |
| 1694 | |
| 1695 | unw_get_reg(&cursor, UNW_REG_IP, &ip); |
| 1696 | unw_get_reg(&cursor, UNW_REG_SP, &sp); |
| 1697 | |
| 1698 | char symbol[256] = {"<unknown>"}; |
| 1699 | char *name = symbol; |
| 1700 | |
| 1701 | if ( !unw_get_proc_name(&cursor, symbol, sizeof(symbol), &off) ) { |
| 1702 | int status; |
| 1703 | if ( (name = abi::__cxa_demangle(symbol, NULL, NULL, &status)) == 0 ) |
| 1704 | name = symbol; |
| 1705 | } |
| 1706 | |
| 1707 | dprintf(fd, "%s(+0x%" PRIxPTR ") [0x%016" PRIxPTR "] sp=0x%016" PRIxPTR "\n", |
| 1708 | name, |
| 1709 | static_cast<uintptr_t>(off), |
| 1710 | static_cast<uintptr_t>(ip), |
| 1711 | static_cast<uintptr_t>(sp)); |
| 1712 | |
| 1713 | if ( name != symbol ) |
| 1714 | free(name); |
| 1715 | } |
| 1716 | } |
| 1717 | |
| 1718 | #endif /* UNW_LOCAL_ONLY */ |
| 1719 |
no test coverage detected