@@ -1663,3 +1663,138 @@ void cmaple::resetStream(std::istream& instream) {
16631663 instream.clear ();
16641664 instream.seekg (0 , ios::beg);
16651665}
1666+
1667+ /* * Print a demangled stack backtrace of the caller function to FILE* out. */
1668+
1669+ #if !defined(Backtrace_FOUND)
1670+
1671+ // donothing for WIN32
1672+ void cmaple::print_backtrace (ostream &out, unsigned int max_frames) {}
1673+
1674+ #else
1675+
1676+ void cmaple::print_backtrace (ostream &out, unsigned int max_frames)
1677+ {
1678+ #ifdef _OPENMP
1679+ #pragma omp master
1680+ {
1681+ #endif
1682+ out << " STACK TRACE FOR DEBUGGING:" << endl;
1683+
1684+ // storage array for stack trace address data
1685+ void * addrlist[max_frames+1 ];
1686+
1687+ // retrieve current stack addresses
1688+ int addrlen = backtrace (addrlist, sizeof (addrlist) / sizeof (void *));
1689+
1690+ // if (addrlen == 0) {
1691+ // out << " <empty, possibly corrupt>" << endl;
1692+ // return;
1693+ // }
1694+
1695+ // resolve addresses into strings containing "filename(function+address)",
1696+ // this array must be free()-ed
1697+ char ** symbollist = backtrace_symbols (addrlist, addrlen);
1698+
1699+ // allocate string which will be filled with the demangled function name
1700+ size_t funcnamesize = 256 ;
1701+ char * funcname = (char *)malloc (funcnamesize);
1702+
1703+ // iterate over the returned symbol lines. skip the first, it is the
1704+ // address of this function.
1705+ for (int i = 1 ; i < addrlen; i++)
1706+ {
1707+ char *begin_name = 0 , *begin_offset = 0 ;
1708+
1709+ // find parentheses and +address offset surrounding the mangled name:
1710+ #ifdef __clang__
1711+ // OSX style stack trace
1712+ for ( char *p = symbollist[i]; *p; ++p )
1713+ {
1714+ if (( *p == ' _' ) && ( *(p-1 ) == ' ' ))
1715+ begin_name = p-1 ;
1716+ else if ( *p == ' +' )
1717+ begin_offset = p-1 ;
1718+ }
1719+
1720+ if ( begin_name && begin_offset && ( begin_name < begin_offset ))
1721+ {
1722+ *begin_name++ = ' \0 ' ;
1723+ *begin_offset++ = ' \0 ' ;
1724+
1725+ // mangled name is now in [begin_name, begin_offset) and caller
1726+ // offset in [begin_offset, end_offset). now apply
1727+ // __cxa_demangle():
1728+ int status;
1729+ char * ret = abi::__cxa_demangle ( begin_name, &funcname[0 ],
1730+ &funcnamesize, &status );
1731+ if ( status == 0 )
1732+ {
1733+ funcname = ret; // use possibly realloc()-ed string
1734+ // out << " " << symbollist[i] << " : " << funcname << "+"<< begin_offset << endl;
1735+ out << i << " " << funcname << endl;
1736+ } else {
1737+ // demangling failed. Output function name as a C function with
1738+ // no arguments.
1739+ // out << " " << symbollist[i] << " : " << begin_name << "()+"<< begin_offset << endl;
1740+ out << i << " " << begin_name << " ()" << endl;
1741+ }
1742+
1743+ #else // !DARWIN - but is posix
1744+ // ./module(function+0x15c) [0x8048a6d]
1745+ char *end_offset = 0 ;
1746+ for (char *p = symbollist[i]; *p; ++p)
1747+ {
1748+ if (*p == ' (' )
1749+ begin_name = p;
1750+ else if (*p == ' +' )
1751+ begin_offset = p;
1752+ else if (*p == ' )' && begin_offset) {
1753+ end_offset = p;
1754+ break ;
1755+ }
1756+ }
1757+
1758+ if (begin_name && begin_offset && end_offset
1759+ && begin_name < begin_offset)
1760+ {
1761+ *begin_name++ = ' \0 ' ;
1762+ *begin_offset++ = ' \0 ' ;
1763+ *end_offset = ' \0 ' ;
1764+
1765+ // mangled name is now in [begin_name, begin_offset) and caller
1766+ // offset in [begin_offset, end_offset). now apply
1767+ // __cxa_demangle():
1768+
1769+ int status;
1770+ char * ret = abi::__cxa_demangle (begin_name,
1771+ funcname, &funcnamesize, &status);
1772+ if (status == 0 ) {
1773+ funcname = ret; // use possibly realloc()-ed string
1774+ // out << " " << symbollist[i] << " : " << funcname << "+"<< begin_offset << endl;
1775+ out << i << " " << funcname << endl;
1776+ }
1777+ else {
1778+ // demangling failed. Output function name as a C function with
1779+ // no arguments.
1780+ // out << " " << symbollist[i] << " : " << begin_name << "()+"<< begin_offset << endl;
1781+ out << i << " " << begin_name << " ()" << endl;
1782+ }
1783+ #endif
1784+ }
1785+ else
1786+ {
1787+ // couldn't parse the line? print the whole line.
1788+ // out << i << ". " << symbollist[i] << endl;
1789+ }
1790+ }
1791+
1792+ free (funcname);
1793+ free (symbollist);
1794+ #ifdef _OPENMP
1795+ }
1796+ #endif
1797+
1798+ }
1799+
1800+ #endif // Backtrace_FOUND
0 commit comments