<p>What methods are there for automatically getting a stack trace on Unix systems? I don't mean just getting a core file or attaching interactively with GDB, but having a SIGSEGV handler that dumps a backtrace to a text file. </p>

<p>Bonus points for the following optional features:</p>

<ul>
<li>Extra information gathering at crash time (eg. config files).</li>
<li>Email a crash info bundle to the developers.</li>
<li>Ability to add this in a <code>dlopen</code>ed shared library</li>
<li>Not requiring a GUI</li>
</ul>

[{'answer_id': 18406, 'author': 'Derek Park', 'author_id': 872, 'author_profile': 'https://Stackoverflow.com/users/872', 'pm_score': 4, 'selected': True, 'text': '<p>If you are on systems with the BSD <a href="http://linux.die.net/man/3/backtrace" rel="nofollow noreferrer"><code>backtrace</code></a> functionality available (Linux, OSX 1.5, BSD of course), you can do this programmatically in your signal handler.</p>\n\n<p>For example (<a href="http://www-128.ibm.com/developerworks/linux/library/l-cppexcep.html?ca=dgr-lnxw07ExceptionTricks" rel="nofollow noreferrer"><code>backtrace</code> code derived from IBM example</a>): </p>\n\n<pre class="lang-c prettyprint-override"><code>#include &lt;execinfo.h&gt;\n#include &lt;signal.h&gt;\n#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n\nvoid sig_handler(int sig)\n{\n    void * array[25];\n    int nSize = backtrace(array, 25);\n    char ** symbols = backtrace_symbols(array, nSize);\n\n    for (int i = 0; i &lt; nSize; i++)\n    {\n        puts(symbols[i]);;\n    }\n\n    free(symbols);\n\n    signal(sig, &amp;sig_handler);\n}\n\nvoid h()\n{\n    kill(0, SIGSEGV);\n}\n\nvoid g()\n{\n    h();\n}\n\nvoid f()\n{\n    g();\n}\n\nint main(int argc, char ** argv)\n{\n    signal(SIGSEGV, &amp;sig_handler);\n    f();\n}\n</code></pre>\n\n<p>Output:</p>\n\n<pre><code>0   a.out                               0x00001f2d sig_handler + 35\n1   libSystem.B.dylib                   0x95f8f09b _sigtramp + 43\n2   ???                                 0xffffffff 0x0 + 4294967295\n3   a.out                               0x00001fb1 h + 26\n4   a.out                               0x00001fbe g + 11\n5   a.out                               0x00001fcb f + 11\n6   a.out                               0x00001ff5 main + 40\n7   a.out                               0x00001ede start + 54\n</code></pre>\n\n<p>This doesn\'t get bonus points for the optional features (except not requiring a GUI), however, it does have the advantage of being very simple, and not requiring any additional libraries or programs.</p>\n'}, {'answer_id': 24039, 'author': 'Kristof Provost', 'author_id': 1466, 'author_profile': 'https://Stackoverflow.com/users/1466', 'pm_score': 2, 'selected': False, 'text': "<p>Dereks solution is probably the best, but here's an alternative anyway:</p>\n\n<p>Recent Linux kernel version allow you to pipe core dumps to a script or program. You could write a script to catch the core dump, collect any extra information you need and mail everything back. \nThis is a global setting though, so it'd apply to any crashing program on the system. It will also require root rights to set up.\nIt can be configured through the /proc/sys/kernel/core_pattern file. Set that to something like ' | /home/myuser/bin/my-core-handler-script'.</p>\n\n<p>The Ubuntu people use this feature as well.</p>\n"}, {'answer_id': 41924, 'author': 'AndersO', 'author_id': 22021, 'author_profile': 'https://Stackoverflow.com/users/22021', 'pm_score': 2, 'selected': False, 'text': '<p>Here is an example of how to get some more info using a demangler. As you can see this one also logs the stacktrace to file.</p>\n\n<pre class="lang-c prettyprint-override"><code>#include &lt;iostream&gt;\n#include &lt;sstream&gt;\n#include &lt;string&gt;\n#include &lt;fstream&gt;\n#include &lt;cxxabi.h&gt;\n\nvoid sig_handler(int sig)\n{\n    std::stringstream stream;\n    void * array[25];\n    int nSize = backtrace(array, 25);\n    char ** symbols = backtrace_symbols(array, nSize);\n    for (unsigned int i = 0; i &lt; size; i++) {\n        int status;\n        char *realname;\n        std::string current = symbols[i];\n        size_t start = current.find("(");\n        size_t end = current.find("+");\n        realname = NULL;\n        if (start != std::string::npos &amp;&amp; end != std::string::npos) {\n            std::string symbol = current.substr(start+1, end-start-1);\n            realname = abi::__cxa_demangle(symbol.c_str(), 0, 0, &amp;status);\n        }\n        if (realname != NULL)\n            stream &lt;&lt; realname &lt;&lt; std::endl;\n        else\n            stream &lt;&lt; symbols[i] &lt;&lt; std::endl;\n        free(realname);\n    }\n    free(symbols);\n    std::cerr &lt;&lt; stream.str();\n    std::ofstream file("/tmp/error.log");\n    if (file.is_open()) {\n        if (file.good())\n            file &lt;&lt; stream.str();\n        file.close();\n    }\n    signal(sig, &amp;sig_handler);\n}\n</code></pre>\n'}, {'answer_id': 305316, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 4, 'selected': False, 'text': '<p>FYI, </p>\n\n<p>the suggested solution (using backtrace_symbols in a signal handler) is dangerously broken. DO NOT USE IT -</p>\n\n<p>Yes, backtrace and backtrace_symbols will produce a backtrace and a translate it to symbolic names, however:</p>\n\n<ol>\n<li><p>backtrace_symbols allocates memory using malloc and you use free to free it -  If you\'re crashing because of memory corruption your malloc arena is very likely to be corrupt  and cause a double fault.</p></li>\n<li><p>malloc and free protect the malloc arena with a lock internally. You might have faulted in the middle of a malloc/free with the lock taken, which will cause these function or anything that calls them to dead lock.</p></li>\n<li><p>You use puts which uses the standard stream, which is also protected by a lock. If you faulted in the middle of a printf you once again have a deadlock.</p></li>\n<li><p>On 32bit platforms (e.g. your normal PC of 2 year ago), the kernel will plant a return address to an internal glibc function instead of your faulting function in your stack, so the single most important piece of information you are interested in - in which function did the program fault, will actually be corrupted on those platform.</p></li>\n</ol>\n\n<p>So, the code in the example is the worst kind of wrong - it LOOKS like it\'s working, but it will really fail you in unexpected ways in production.</p>\n\n<p>BTW, interested in doing it right? check <a href="http://tuxology.net/lectures/crash-and-burn-writing-linux-application-fault-handlers/" rel="noreferrer">this</a> out. </p>\n\n<p>Cheers,\nGilad.</p>\n'}]
['https://Stackoverflow.com/questions/18265', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/954/']