<p>I am working on Linux with the GCC compiler. When my C++ program crashes I would like it to automatically generate a stacktrace.</p>

<p>My program is being run by many different users and it also runs on Linux, Windows and Macintosh (all versions are compiled using <code>gcc</code>).</p>

<p>I would like my program to be able to generate a stack trace when it crashes and the next time the user runs it, it will ask them if it is ok to send the stack trace to me so I can track down the problem. I can handle the sending the info to me but I don't know how to generate the trace string. Any ideas?</p>

[{'answer_id': 76867, 'author': 'mana', 'author_id': 12016, 'author_profile': 'https://Stackoverflow.com/users/12016', 'pm_score': 3, 'selected': False, 'text': '<pre><code>ulimit -c unlimited\n</code></pre>\n\n<p>is a system variable, wich will allow to create a core dump after your application crashes. In this case an unlimited amount. Look for a file called core in the very same directory. Make sure you compiled your code with debugging informations enabled!</p>\n\n<p>regards</p>\n'}, {'answer_id': 76924, 'author': 'Stephen Deken', 'author_id': 7154, 'author_profile': 'https://Stackoverflow.com/users/7154', 'pm_score': 3, 'selected': False, 'text': '<p>Some versions of libc contain functions that deal with stack traces; you might be able to use them:</p>\n\n<p><a href="http://www.gnu.org/software/libc/manual/html_node/Backtraces.html" rel="noreferrer">http://www.gnu.org/software/libc/manual/html_node/Backtraces.html</a></p>\n\n<p>I remember using <a href="http://www.nongnu.org/libunwind/" rel="noreferrer">libunwind</a> a long time ago to get stack traces, but it may not be supported on your platform.</p>\n'}, {'answer_id': 76937, 'author': 'Brian Mitchell', 'author_id': 13716, 'author_profile': 'https://Stackoverflow.com/users/13716', 'pm_score': 5, 'selected': False, 'text': "<p>You did not specify your operating system, so this is difficult to answer. If you are using a system based on gnu libc, you might be able to use the libc function <code>backtrace()</code>.</p>\n\n<p>GCC also has two builtins that can assist you, but which may or may not be implemented fully on your architecture, and those are <code>__builtin_frame_address</code> and <code>__builtin_return_address</code>. Both of which want an immediate integer level (by immediate, I mean it can't be a variable). If <code>__builtin_frame_address</code> for a given level is non-zero, it should be safe to grab the return address of the same level.</p>\n"}, {'answer_id': 76962, 'author': 'Stéphane', 'author_id': 13022, 'author_profile': 'https://Stackoverflow.com/users/13022', 'pm_score': 3, 'selected': False, 'text': '<p>Look at:</p>\n\n<p>man 3 backtrace</p>\n\n<p>And:</p>\n\n<pre><code>#include &lt;exeinfo.h&gt;\nint backtrace(void **buffer, int size);\n</code></pre>\n\n<p>These are GNU extensions.</p>\n'}, {'answer_id': 76986, 'author': 'Benson', 'author_id': 13816, 'author_profile': 'https://Stackoverflow.com/users/13816', 'pm_score': 4, 'selected': False, 'text': '<p>It\'s important to note that once you generate a core file you\'ll need to use the gdb tool to look at it.  For gdb to make sense of your core file, you must tell gcc to instrument the binary with debugging symbols: to do this, you compile with the -g flag:</p>\n\n<pre><code>$ g++ -g prog.cpp -o prog\n</code></pre>\n\n<p>Then, you can either set "ulimit -c unlimited" to let it dump a core, or just run your program inside gdb.  I like the second approach more: </p>\n\n<pre><code>$ gdb ./prog\n... gdb startup output ...\n(gdb) run\n... program runs and crashes ...\n(gdb) where\n... gdb outputs your stack trace ...\n</code></pre>\n\n<p>I hope this helps.  </p>\n'}, {'answer_id': 77030, 'author': 'Jim Buck', 'author_id': 2666, 'author_profile': 'https://Stackoverflow.com/users/2666', 'pm_score': 2, 'selected': False, 'text': '<p>I would use the code that generates a stack trace for leaked memory in <a href="http://www.codeproject.com/KB/applications/visualleakdetector.aspx" rel="nofollow noreferrer">Visual Leak Detector</a>. This only works on Win32, though.</p>\n'}, {'answer_id': 77033, 'author': 'terminus', 'author_id': 9232, 'author_profile': 'https://Stackoverflow.com/users/9232', 'pm_score': 3, 'selected': False, 'text': '<p>I can help with the Linux version: the function backtrace, backtrace_symbols and backtrace_symbols_fd can be used. See the corresponding manual pages.</p>\n'}, {'answer_id': 77142, 'author': 'INS', 'author_id': 13136, 'author_profile': 'https://Stackoverflow.com/users/13136', 'pm_score': 2, 'selected': False, 'text': '<p>*nix: \nyou can intercept <a href="http://en.wikipedia.org/wiki/SIGSEGV" rel="nofollow noreferrer">SIGSEGV</a> (usualy this signal is raised before crashing) and keep the info into a file. (besides the core file which you can use to debug using gdb for example).</p>\n\n<p>win:\nCheck <a href="http://msdn.microsoft.com/en-us/library/ms680659(VS.85).aspx" rel="nofollow noreferrer">this</a> from msdn.</p>\n\n<p>You can also look at the google\'s chrome code to see how it handles crashes. It has a nice exception handling mechanism.</p>\n'}, {'answer_id': 77224, 'author': 'Kasprzol', 'author_id': 5957, 'author_profile': 'https://Stackoverflow.com/users/5957', 'pm_score': 1, 'selected': False, 'text': '<p>On Linux/unix/MacOSX use core files (you can enable them with ulimit or <a href="http://www.opengroup.org/onlinepubs/009695399/functions/setrlimit.html" rel="nofollow noreferrer">compatible system call</a>). On Windows use Microsoft error reporting (you can become a partner and get access to your application crash data).</p>\n'}, {'answer_id': 77272, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 4, 'selected': False, 'text': '<p><code>ulimit -c &lt;value&gt;</code> sets the core file size limit on unix.  By default, the core file size limit is 0.  You can see your <code>ulimit</code> values with <code>ulimit -a</code>.</p>\n\n<p>also, if you run your program from within gdb, it will halt your program on "segmentation violations" (<code>SIGSEGV</code>, generally when you accessed a piece of memory that you hadn\'t allocated) or you can set breakpoints.</p>\n\n<p>ddd and nemiver are front-ends for gdb which make working with it much easier for the novice.</p>\n'}, {'answer_id': 77289, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': '<p>I forgot about the GNOME tech of "apport", but I don\'t know much about using it.  It is used to generate stacktraces and other diagnostics for processing and can automatically file bugs.  It\'s certainly worth checking in to.</p>\n'}, {'answer_id': 77336, 'author': 'Todd Gamblin', 'author_id': 9122, 'author_profile': 'https://Stackoverflow.com/users/9122', 'pm_score': 10, 'selected': True, 'text': '<p>For Linux and I believe Mac OS X, if you\'re using gcc, or any compiler that uses glibc, you can use the backtrace() functions in <code>execinfo.h</code> to print a stacktrace and exit gracefully when you get a segmentation fault.  Documentation can be found <a href="http://www.gnu.org/software/libc/manual/html_node/Backtraces.html" rel="noreferrer">in the libc manual</a>.</p>\n\n<p>Here\'s an example program that installs a <code>SIGSEGV</code> handler and prints a stacktrace to <code>stderr</code> when it segfaults.  The <code>baz()</code> function here causes the segfault that triggers the handler:</p>\n\n<pre><code>#include &lt;stdio.h&gt;\n#include &lt;execinfo.h&gt;\n#include &lt;signal.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;unistd.h&gt;\n\n\nvoid handler(int sig) {\n  void *array[10];\n  size_t size;\n\n  // get void*\'s for all entries on the stack\n  size = backtrace(array, 10);\n\n  // print out all the frames to stderr\n  fprintf(stderr, "Error: signal %d:\\n", sig);\n  backtrace_symbols_fd(array, size, STDERR_FILENO);\n  exit(1);\n}\n\nvoid baz() {\n int *foo = (int*)-1; // make a bad pointer\n  printf("%d\\n", *foo);       // causes segfault\n}\n\nvoid bar() { baz(); }\nvoid foo() { bar(); }\n\n\nint main(int argc, char **argv) {\n  signal(SIGSEGV, handler);   // install our handler\n  foo(); // this will call foo, bar, and baz.  baz segfaults.\n}\n</code></pre>\n\n<p>Compiling with <code>-g -rdynamic</code> gets you symbol info in your output, which glibc can use to make a nice stacktrace:</p>\n\n<pre><code>$ gcc -g -rdynamic ./test.c -o test\n</code></pre>\n\n<p>Executing this gets you this output:</p>\n\n<pre><code>$ ./test\nError: signal 11:\n./test(handler+0x19)[0x400911]\n/lib64/tls/libc.so.6[0x3a9b92e380]\n./test(baz+0x14)[0x400962]\n./test(bar+0xe)[0x400983]\n./test(foo+0xe)[0x400993]\n./test(main+0x28)[0x4009bd]\n/lib64/tls/libc.so.6(__libc_start_main+0xdb)[0x3a9b91c4bb]\n./test[0x40086a]\n</code></pre>\n\n<p>This shows the load module, offset, and function that each frame in the stack came from.  Here you can see the signal handler on top of the stack, and the libc functions before <code>main</code> in addition to <code>main</code>, <code>foo</code>, <code>bar</code>, and <code>baz</code>.</p>\n'}, {'answer_id': 78543, 'author': 'Adam Mitz', 'author_id': 2574, 'author_profile': 'https://Stackoverflow.com/users/2574', 'pm_score': 3, 'selected': False, 'text': '<p>See the Stack Trace facility in <a href="http://www.cs.wustl.edu/~schmidt/ACE.html" rel="noreferrer">ACE</a> (ADAPTIVE Communication Environment).  It\'s already written to cover all major platforms (and more).  The library is BSD-style licensed so you can even copy/paste the code if you don\'t want to use ACE.</p>\n'}, {'answer_id': 82192, 'author': 'Simon Steele', 'author_id': 4591, 'author_profile': 'https://Stackoverflow.com/users/4591', 'pm_score': 5, 'selected': False, 'text': '<p>Might be worth looking at <a href="https://chromium.googlesource.com/breakpad/breakpad" rel="noreferrer">Google Breakpad</a>, a cross-platform crash dump generator and tools to process the dumps.</p>\n'}, {'answer_id': 89601, 'author': 'Gregory', 'author_id': 14351, 'author_profile': 'https://Stackoverflow.com/users/14351', 'pm_score': 4, 'selected': False, 'text': '<p>Ive been looking at this problem for a while.</p>\n\n<p>And buried deep in the Google Performance Tools README</p>\n\n<p><a href="http://code.google.com/p/google-perftools/source/browse/trunk/README" rel="noreferrer">http://code.google.com/p/google-perftools/source/browse/trunk/README</a></p>\n\n<p>talks about libunwind</p>\n\n<p><a href="http://www.nongnu.org/libunwind/" rel="noreferrer">http://www.nongnu.org/libunwind/</a></p>\n\n<p>Would love to hear opinions of this library.</p>\n\n<p>The problem with -rdynamic is that it can increase the size of the binary relatively significantly in some cases</p>\n'}, {'answer_id': 1925461, 'author': 'jschmier', 'author_id': 203667, 'author_profile': 'https://Stackoverflow.com/users/203667', 'pm_score': 7, 'selected': False, 'text': '<h2>Linux</h2>\n<p>While the use of the backtrace() functions in execinfo.h to print a stacktrace and exit gracefully when you get a segmentation fault has <a href="https://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace-when-my-gcc-c-app-crashes/77336#77336">already been suggested</a>, I see no mention of the intricacies necessary to ensure the resulting backtrace points to the actual location of the fault (at least for some architectures - x86 &amp; ARM).</p>\n<p>The first two entries in the stack frame chain when you get into the signal handler contain a return address inside the signal handler and one inside sigaction() in libc. The stack frame of the last function called before the signal (which is the location of the fault) is lost.</p>\n<h2>Code</h2>\n<pre><code>#ifndef _GNU_SOURCE\n#define _GNU_SOURCE\n#endif\n#ifndef __USE_GNU\n#define __USE_GNU\n#endif\n\n#include &lt;execinfo.h&gt;\n#include &lt;signal.h&gt;\n#include &lt;stdio.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;string.h&gt;\n#include &lt;ucontext.h&gt;\n#include &lt;unistd.h&gt;\n\n/* This structure mirrors the one found in /usr/include/asm/ucontext.h */\ntypedef struct _sig_ucontext {\n unsigned long     uc_flags;\n ucontext_t        *uc_link;\n stack_t           uc_stack;\n sigcontext_t      uc_mcontext;\n sigset_t          uc_sigmask;\n} sig_ucontext_t;\n\nvoid crit_err_hdlr(int sig_num, siginfo_t * info, void * ucontext)\n{\n void *             array[50];\n void *             caller_address;\n char **            messages;\n int                size, i;\n sig_ucontext_t *   uc;\n\n uc = (sig_ucontext_t *)ucontext;\n\n /* Get the address at the time the signal was raised */\n#if defined(__i386__) // gcc specific\n caller_address = (void *) uc-&gt;uc_mcontext.eip; // EIP: x86 specific\n#elif defined(__x86_64__) // gcc specific\n caller_address = (void *) uc-&gt;uc_mcontext.rip; // RIP: x86_64 specific\n#else\n#error Unsupported architecture. // TODO: Add support for other arch.\n#endif\n\n fprintf(stderr, &quot;signal %d (%s), address is %p from %p\\n&quot;, \n  sig_num, strsignal(sig_num), info-&gt;si_addr, \n  (void *)caller_address);\n\n size = backtrace(array, 50);\n\n /* overwrite sigaction with caller\'s address */\n array[1] = caller_address;\n\n messages = backtrace_symbols(array, size);\n\n /* skip first stack frame (points here) */\n for (i = 1; i &lt; size &amp;&amp; messages != NULL; ++i)\n {\n  fprintf(stderr, &quot;[bt]: (%d) %s\\n&quot;, i, messages[i]);\n }\n\n free(messages);\n\n exit(EXIT_FAILURE);\n}\n\nint crash()\n{\n char * p = NULL;\n *p = 0;\n return 0;\n}\n\nint foo4()\n{\n crash();\n return 0;\n}\n\nint foo3()\n{\n foo4();\n return 0;\n}\n\nint foo2()\n{\n foo3();\n return 0;\n}\n\nint foo1()\n{\n foo2();\n return 0;\n}\n\nint main(int argc, char ** argv)\n{\n struct sigaction sigact;\n\n sigact.sa_sigaction = crit_err_hdlr;\n sigact.sa_flags = SA_RESTART | SA_SIGINFO;\n\n if (sigaction(SIGSEGV, &amp;sigact, (struct sigaction *)NULL) != 0)\n {\n  fprintf(stderr, &quot;error setting signal handler for %d (%s)\\n&quot;,\n    SIGSEGV, strsignal(SIGSEGV));\n\n  exit(EXIT_FAILURE);\n }\n\n foo1();\n\n exit(EXIT_SUCCESS);\n}\n</code></pre>\n<h2>Output</h2>\n<pre><code>signal 11 (Segmentation fault), address is (nil) from 0x8c50\n[bt]: (1) ./test(crash+0x24) [0x8c50]\n[bt]: (2) ./test(foo4+0x10) [0x8c70]\n[bt]: (3) ./test(foo3+0x10) [0x8c8c]\n[bt]: (4) ./test(foo2+0x10) [0x8ca8]\n[bt]: (5) ./test(foo1+0x10) [0x8cc4]\n[bt]: (6) ./test(main+0x74) [0x8d44]\n[bt]: (7) /lib/libc.so.6(__libc_start_main+0xa8) [0x40032e44]\n</code></pre>\n<p>All the hazards of calling the backtrace() functions in a signal handler still exist and should not be overlooked, but I find the functionality I described here quite helpful in debugging crashes.</p>\n<p>It is important to note that the example I provided is developed/tested on Linux for x86.  I have also successfully implemented this on ARM using <code>uc_mcontext.arm_pc</code> instead of <code>uc_mcontext.eip</code>.</p>\n<p>Here\'s a link to the article where I learned the details for this implementation:\n<a href="http://www.linuxjournal.com/article/6391" rel="noreferrer">http://www.linuxjournal.com/article/6391</a></p>\n'}, {'answer_id': 2526298, 'author': 'jschmier', 'author_id': 203667, 'author_profile': 'https://Stackoverflow.com/users/203667', 'pm_score': 7, 'selected': False, 'text': '<p>Even though a <a href="https://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace-when-my-gcc-c-app-crashes/77336#77336">correct answer</a> has been provided that describes how to use the GNU libc <code>backtrace()</code> function<sup>1</sup> and I provided <a href="https://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace-when-my-gcc-c-app-crashes/1925461#1925461">my own answer</a> that describes how to ensure a backtrace from a signal handler points to the actual location of the fault<sup>2</sup>, I don\'t see any mention of <a href="http://en.wikipedia.org/wiki/Name_mangling" rel="noreferrer">demangling</a> C++ symbols output from the backtrace.</p>\n\n<p>When obtaining backtraces from a C++ program, the output can be run through <code>c++filt</code><sup>1</sup> to demangle the symbols or by using <a href="http://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html" rel="noreferrer"><code>abi::__cxa_demangle</code></a><sup>1</sup> directly.</p>\n\n<ul>\n<li><sup>1</sup>  Linux &amp; OS X\n<sub>Note that <code>c++filt</code> and <code>__cxa_demangle</code> are GCC specific</sub></li>\n<li><sup>2</sup>  Linux</li>\n</ul>\n\n<hr>\n\n<p>The following C++ Linux example uses the same signal handler as my <a href="https://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace-when-my-gcc-c-app-crashes/1925461#1925461">other answer</a> and demonstrates how <code>c++filt</code> can be used to demangle the symbols.</p>\n\n<p><strong>Code</strong>:</p>\n\n<pre><code>class foo\n{\npublic:\n    foo() { foo1(); }\n\nprivate:\n    void foo1() { foo2(); }\n    void foo2() { foo3(); }\n    void foo3() { foo4(); }\n    void foo4() { crash(); }\n    void crash() { char * p = NULL; *p = 0; }\n};\n\nint main(int argc, char ** argv)\n{\n    // Setup signal handler for SIGSEGV\n    ...\n\n    foo * f = new foo();\n    return 0;\n}\n</code></pre>\n\n<p><strong>Output</strong> (<code>./test</code>):</p>\n\n<pre><code>signal 11 (Segmentation fault), address is (nil) from 0x8048e07\n[bt]: (1) ./test(crash__3foo+0x13) [0x8048e07]\n[bt]: (2) ./test(foo4__3foo+0x12) [0x8048dee]\n[bt]: (3) ./test(foo3__3foo+0x12) [0x8048dd6]\n[bt]: (4) ./test(foo2__3foo+0x12) [0x8048dbe]\n[bt]: (5) ./test(foo1__3foo+0x12) [0x8048da6]\n[bt]: (6) ./test(__3foo+0x12) [0x8048d8e]\n[bt]: (7) ./test(main+0xe0) [0x8048d18]\n[bt]: (8) ./test(__libc_start_main+0x95) [0x42017589]\n[bt]: (9) ./test(__register_frame_info+0x3d) [0x8048981]\n</code></pre>\n\n<p><strong>Demangled Output</strong> (<code>./test 2&gt;&amp;1 | c++filt</code>):</p>\n\n<pre><code>signal 11 (Segmentation fault), address is (nil) from 0x8048e07\n[bt]: (1) ./test(foo::crash(void)+0x13) [0x8048e07]\n[bt]: (2) ./test(foo::foo4(void)+0x12) [0x8048dee]\n[bt]: (3) ./test(foo::foo3(void)+0x12) [0x8048dd6]\n[bt]: (4) ./test(foo::foo2(void)+0x12) [0x8048dbe]\n[bt]: (5) ./test(foo::foo1(void)+0x12) [0x8048da6]\n[bt]: (6) ./test(foo::foo(void)+0x12) [0x8048d8e]\n[bt]: (7) ./test(main+0xe0) [0x8048d18]\n[bt]: (8) ./test(__libc_start_main+0x95) [0x42017589]\n[bt]: (9) ./test(__register_frame_info+0x3d) [0x8048981]\n</code></pre>\n\n<hr>\n\n<p>The following builds on the signal handler from my <a href="https://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace-when-my-gcc-c-app-crashes/1925461#1925461">original answer</a> and can replace the signal handler in the above example to demonstrate how <a href="http://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html" rel="noreferrer"><code>abi::__cxa_demangle</code></a> can be used to demangle the symbols.  This signal handler produces the same demangled output as the above example.</p>\n\n<p><strong>Code</strong>:</p>\n\n<pre><code>void crit_err_hdlr(int sig_num, siginfo_t * info, void * ucontext)\n{\n    sig_ucontext_t * uc = (sig_ucontext_t *)ucontext;\n\n    void * caller_address = (void *) uc-&gt;uc_mcontext.eip; // x86 specific\n\n    std::cerr &lt;&lt; "signal " &lt;&lt; sig_num \n              &lt;&lt; " (" &lt;&lt; strsignal(sig_num) &lt;&lt; "), address is " \n              &lt;&lt; info-&gt;si_addr &lt;&lt; " from " &lt;&lt; caller_address \n              &lt;&lt; std::endl &lt;&lt; std::endl;\n\n    void * array[50];\n    int size = backtrace(array, 50);\n\n    array[1] = caller_address;\n\n    char ** messages = backtrace_symbols(array, size);    \n\n    // skip first stack frame (points here)\n    for (int i = 1; i &lt; size &amp;&amp; messages != NULL; ++i)\n    {\n        char *mangled_name = 0, *offset_begin = 0, *offset_end = 0;\n\n        // find parantheses and +address offset surrounding mangled name\n        for (char *p = messages[i]; *p; ++p)\n        {\n            if (*p == \'(\') \n            {\n                mangled_name = p; \n            }\n            else if (*p == \'+\') \n            {\n                offset_begin = p;\n            }\n            else if (*p == \')\')\n            {\n                offset_end = p;\n                break;\n            }\n        }\n\n        // if the line could be processed, attempt to demangle the symbol\n        if (mangled_name &amp;&amp; offset_begin &amp;&amp; offset_end &amp;&amp; \n            mangled_name &lt; offset_begin)\n        {\n            *mangled_name++ = \'\\0\';\n            *offset_begin++ = \'\\0\';\n            *offset_end++ = \'\\0\';\n\n            int status;\n            char * real_name = abi::__cxa_demangle(mangled_name, 0, 0, &amp;status);\n\n            // if demangling is successful, output the demangled function name\n            if (status == 0)\n            {    \n                std::cerr &lt;&lt; "[bt]: (" &lt;&lt; i &lt;&lt; ") " &lt;&lt; messages[i] &lt;&lt; " : " \n                          &lt;&lt; real_name &lt;&lt; "+" &lt;&lt; offset_begin &lt;&lt; offset_end \n                          &lt;&lt; std::endl;\n\n            }\n            // otherwise, output the mangled function name\n            else\n            {\n                std::cerr &lt;&lt; "[bt]: (" &lt;&lt; i &lt;&lt; ") " &lt;&lt; messages[i] &lt;&lt; " : " \n                          &lt;&lt; mangled_name &lt;&lt; "+" &lt;&lt; offset_begin &lt;&lt; offset_end \n                          &lt;&lt; std::endl;\n            }\n            free(real_name);\n        }\n        // otherwise, print the whole line\n        else\n        {\n            std::cerr &lt;&lt; "[bt]: (" &lt;&lt; i &lt;&lt; ") " &lt;&lt; messages[i] &lt;&lt; std::endl;\n        }\n    }\n    std::cerr &lt;&lt; std::endl;\n\n    free(messages);\n\n    exit(EXIT_FAILURE);\n}\n</code></pre>\n'}, {'answer_id': 6599348, 'author': 'jhclark', 'author_id': 758067, 'author_profile': 'https://Stackoverflow.com/users/758067', 'pm_score': 7, 'selected': False, 'text': '<p>It\'s even easier than "man backtrace", there\'s a little-documented library (GNU specific) distributed with glibc as libSegFault.so, which was I believe was written by Ulrich Drepper to support the program catchsegv (see "man catchsegv").</p>\n\n<p>This gives us 3 possibilities. Instead of running "program -o hai":</p>\n\n<ol>\n<li><p>Run within catchsegv:</p>\n\n<pre><code>$ catchsegv program -o hai\n</code></pre></li>\n<li><p>Link with libSegFault at runtime:</p>\n\n<pre><code>$ LD_PRELOAD=/lib/libSegFault.so program -o hai\n</code></pre></li>\n<li><p>Link with libSegFault at compile time:</p>\n\n<pre><code>$ gcc -g1 -lSegFault -o program program.cc\n$ program -o hai\n</code></pre></li>\n</ol>\n\n<p>In all 3 cases, you will get clearer backtraces with less optimization (gcc -O0 or -O1) and debugging symbols (gcc -g). Otherwise, you may just end up with a pile of memory addresses.</p>\n\n<p>You can also catch more signals for stack traces with something like:</p>\n\n<pre><code>$ export SEGFAULT_SIGNALS="all"       # "all" signals\n$ export SEGFAULT_SIGNALS="bus abrt"  # SIGBUS and SIGABRT\n</code></pre>\n\n<p>The output will look something like this (notice the backtrace at the bottom):</p>\n\n<pre><code>*** Segmentation fault Register dump:\n\n EAX: 0000000c   EBX: 00000080   ECX:\n00000000   EDX: 0000000c  ESI:\nbfdbf080   EDI: 080497e0   EBP:\nbfdbee38   ESP: bfdbee20\n\n EIP: 0805640f   EFLAGS: 00010282\n\n CS: 0073   DS: 007b   ES: 007b   FS:\n0000   GS: 0033   SS: 007b\n\n Trap: 0000000e   Error: 00000004  \nOldMask: 00000000  ESP/signal:\nbfdbee20   CR2: 00000024\n\n FPUCW: ffff037f   FPUSW: ffff0000  \nTAG: ffffffff  IPOFF: 00000000  \nCSSEL: 0000   DATAOFF: 00000000  \nDATASEL: 0000\n\n ST(0) 0000 0000000000000000   ST(1)\n0000 0000000000000000  ST(2) 0000\n0000000000000000   ST(3) 0000\n0000000000000000  ST(4) 0000\n0000000000000000   ST(5) 0000\n0000000000000000  ST(6) 0000\n0000000000000000   ST(7) 0000\n0000000000000000\n\nBacktrace:\n/lib/libSegFault.so[0xb7f9e100]\n??:0(??)[0xb7fa3400]\n/usr/include/c++/4.3/bits/stl_queue.h:226(_ZNSt5queueISsSt5dequeISsSaISsEEE4pushERKSs)[0x805647a]\n/home/dbingham/src/middle-earth-mud/alpha6/src/engine/player.cpp:73(_ZN6Player5inputESs)[0x805377c]\n/home/dbingham/src/middle-earth-mud/alpha6/src/engine/socket.cpp:159(_ZN6Socket4ReadEv)[0x8050698]\n/home/dbingham/src/middle-earth-mud/alpha6/src/engine/socket.cpp:413(_ZN12ServerSocket4ReadEv)[0x80507ad]\n/home/dbingham/src/middle-earth-mud/alpha6/src/engine/socket.cpp:300(_ZN12ServerSocket4pollEv)[0x8050b44]\n/home/dbingham/src/middle-earth-mud/alpha6/src/engine/main.cpp:34(main)[0x8049a72]\n/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe5)[0xb7d1b775]\n/build/buildd/glibc-2.9/csu/../sysdeps/i386/elf/start.S:122(_start)[0x8049801]\n</code></pre>\n\n<p>If you want to know the gory details, the best source is unfortunately the source: See <a href="http://sourceware.org/git/?p=glibc.git;a=blob;f=debug/segfault.c" rel="noreferrer">http://sourceware.org/git/?p=glibc.git;a=blob;f=debug/segfault.c</a> and its parent directory <a href="http://sourceware.org/git/?p=glibc.git;a=tree;f=debug" rel="noreferrer">http://sourceware.org/git/?p=glibc.git;a=tree;f=debug</a> </p>\n'}, {'answer_id': 15152011, 'author': 'markhor', 'author_id': 69708, 'author_profile': 'https://Stackoverflow.com/users/69708', 'pm_score': 3, 'selected': False, 'text': '<p>You can use <a href="https://github.com/vmarkovtsev/DeathHandler" rel="noreferrer" title="DeathHandler">DeathHandler</a> - small C++ class which does everything for you, reliable.</p>\n'}, {'answer_id': 15801966, 'author': 'arr_sea', 'author_id': 1797414, 'author_profile': 'https://Stackoverflow.com/users/1797414', 'pm_score': 4, 'selected': False, 'text': '<p>Thank you to enthusiasticgeek for drawing my attention to the addr2line utility.</p>\n\n<p>I\'ve written a quick and dirty script to process the output of the answer provided <a href="https://stackoverflow.com/a/1925461/1797414">here</a>:\n(much thanks to jschmier!) using the addr2line utility.</p>\n\n<p>The script accepts a single argument: The name of the file containing the output from jschmier\'s utility.</p>\n\n<p>The output should print something like the following for each level of the trace:</p>\n\n<pre><code>BACKTRACE:  testExe 0x8A5db6b\nFILE:       pathToFile/testExe.C:110\nFUNCTION:   testFunction(int) \n   107  \n   108           \n   109           int* i = 0x0;\n  *110           *i = 5;\n   111      \n   112        }\n   113        return i;\n</code></pre>\n\n<p>Code:</p>\n\n<pre><code>#!/bin/bash\n\nLOGFILE=$1\n\nNUM_SRC_CONTEXT_LINES=3\n\nold_IFS=$IFS  # save the field separator           \nIFS=$\'\\n\'     # new field separator, the end of line           \n\nfor bt in `cat $LOGFILE | grep \'\\[bt\\]\'`; do\n   IFS=$old_IFS     # restore default field separator \n   printf \'\\n\'\n   EXEC=`echo $bt | cut -d\' \' -f3 | cut -d\'(\' -f1`  \n   ADDR=`echo $bt | cut -d\'[\' -f3 | cut -d\']\' -f1`\n   echo "BACKTRACE:  $EXEC $ADDR"\n   A2L=`addr2line -a $ADDR -e $EXEC -pfC`\n   #echo "A2L:        $A2L"\n\n   FUNCTION=`echo $A2L | sed \'s/\\&lt;at\\&gt;.*//\' | cut -d\' \' -f2-99`\n   FILE_AND_LINE=`echo $A2L | sed \'s/.* at //\'`\n   echo "FILE:       $FILE_AND_LINE"\n   echo "FUNCTION:   $FUNCTION"\n\n   # print offending source code\n   SRCFILE=`echo $FILE_AND_LINE | cut -d\':\' -f1`\n   LINENUM=`echo $FILE_AND_LINE | cut -d\':\' -f2`\n   if ([ -f $SRCFILE ]); then\n      cat -n $SRCFILE | grep -C $NUM_SRC_CONTEXT_LINES "^ *$LINENUM\\&gt;" | sed "s/ $LINENUM/*$LINENUM/"\n   else\n      echo "File not found: $SRCFILE"\n   fi\n   IFS=$\'\\n\'     # new field separator, the end of line           \ndone\n\nIFS=$old_IFS     # restore default field separator \n</code></pre>\n'}, {'answer_id': 16448454, 'author': 'enthusiasticgeek', 'author_id': 264683, 'author_profile': 'https://Stackoverflow.com/users/264683', 'pm_score': 2, 'selected': False, 'text': "<p>In addition to above answers, here how you make Debian Linux OS generate core dump </p>\n\n<ol>\n<li>Create a “coredumps” folder in the user's home folder</li>\n<li>Go to /etc/security/limits.conf. Below the '   ' line, type “ soft core unlimited”, and “root soft core unlimited” if enabling core dumps for root, to allow unlimited space for core dumps. </li>\n<li>NOTE: “* soft core unlimited” does not cover root, which is why root has to be specified in its own line.</li>\n<li>To check these values, log out, log back in, and type “ulimit -a”. “Core file size” should be set to unlimited.</li>\n<li>Check the .bashrc files (user, and root if applicable) to make sure that ulimit is not set there. Otherwise, the value above will be overwritten on startup.</li>\n<li>Open /etc/sysctl.conf. \nEnter the following at the bottom: “kernel.core_pattern = /home//coredumps/%e_%t.dump”. (%e will be the process name, and %t will be the system time)</li>\n<li>Exit and type “sysctl -p” to load the new configuration\nCheck /proc/sys/kernel/core_pattern and verify that this matches what you just typed in.</li>\n<li>Core dumping can be tested by running a process on the command line (“ &amp;”), and then killing it with “kill -11 ”. If core dumping is successful, you will see “(core dumped)” after the segmentation fault indication.</li>\n</ol>\n"}, {'answer_id': 20556298, 'author': 'jard18', 'author_id': 2980910, 'author_profile': 'https://Stackoverflow.com/users/2980910', 'pm_score': 2, 'selected': False, 'text': "<p>I have seen a lot of answers here performing a signal handler and then exiting.\nThat's the way to go, but remember a very important fact: If you want to get the core dump for the generated error, you can't call <code>exit(status)</code>. Call <code>abort()</code> instead!</p>\n"}, {'answer_id': 22532288, 'author': 'Daniil Iaitskov', 'author_id': 342882, 'author_profile': 'https://Stackoverflow.com/users/342882', 'pm_score': 2, 'selected': False, 'text': '<p>I found that @tgamblin solution is not complete.\nIt cannot handle with stackoverflow.\nI think because by default signal handler is called with the same stack and\nSIGSEGV is thrown twice. To protect you need register an independent stack for the signal handler.</p>\n\n<p>You can check this with code below. By default the handler fails. With defined macro STACK_OVERFLOW it\'s all right.</p>\n\n<pre><code>#include &lt;iostream&gt;\n#include &lt;execinfo.h&gt;\n#include &lt;signal.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;unistd.h&gt;\n#include &lt;string&gt;\n#include &lt;cassert&gt;\n\nusing namespace std;\n\n//#define STACK_OVERFLOW\n\n#ifdef STACK_OVERFLOW\nstatic char stack_body[64*1024];\nstatic stack_t sigseg_stack;\n#endif\n\nstatic struct sigaction sigseg_handler;\n\nvoid handler(int sig) {\n  cerr &lt;&lt; "sig seg fault handler" &lt;&lt; endl;\n  const int asize = 10;\n  void *array[asize];\n  size_t size;\n\n  // get void*\'s for all entries on the stack\n  size = backtrace(array, asize);\n\n  // print out all the frames to stderr\n  cerr &lt;&lt; "stack trace: " &lt;&lt; endl;\n  backtrace_symbols_fd(array, size, STDERR_FILENO);\n  cerr &lt;&lt; "resend SIGSEGV to get core dump" &lt;&lt; endl;\n  signal(sig, SIG_DFL);\n  kill(getpid(), sig);\n}\n\nvoid foo() {\n  foo();\n}\n\nint main(int argc, char **argv) {\n#ifdef STACK_OVERFLOW\n  sigseg_stack.ss_sp = stack_body;\n  sigseg_stack.ss_flags = SS_ONSTACK;\n  sigseg_stack.ss_size = sizeof(stack_body);\n  assert(!sigaltstack(&amp;sigseg_stack, nullptr));\n  sigseg_handler.sa_flags = SA_ONSTACK;\n#else\n  sigseg_handler.sa_flags = SA_RESTART;  \n#endif\n  sigseg_handler.sa_handler = &amp;handler;\n  assert(!sigaction(SIGSEGV, &amp;sigseg_handler, nullptr));\n  cout &lt;&lt; "sig action set" &lt;&lt; endl;\n  foo();\n  return 0;\n} \n</code></pre>\n'}, {'answer_id': 38224204, 'author': 'loopzilla', 'author_id': 4182817, 'author_profile': 'https://Stackoverflow.com/users/4182817', 'pm_score': 3, 'selected': False, 'text': '<p>Forget about changing your sources and do some hacks with backtrace() function or macroses - these are just poor solutions.</p>\n\n<p>As a properly working solution, I would advice:</p>\n\n<ol>\n<li>Compile your program with "-g" flag for embedding debug symbols to binary (don\'t worry this will not impact your performance). </li>\n<li>On linux run next command: "ulimit -c unlimited" - to allow system make big crash dumps.</li>\n<li>When your program crashed, in the working directory you will see file "core".</li>\n<li>Run next command to print backtrace to stdout: gdb -batch -ex "backtrace" ./your_program_exe ./core</li>\n</ol>\n\n<p>This will print proper readable backtrace of your program in human readable way (with source file names and line numbers).\nMoreover this approach will give you freedom to automatize your system:\nhave a short script that checks if process created a core dump, and then send backtraces by email to developers, or log this into some logging system.</p>\n'}, {'answer_id': 41404312, 'author': 'Roy', 'author_id': 1040618, 'author_profile': 'https://Stackoverflow.com/users/1040618', 'pm_score': 4, 'selected': False, 'text': '<p>The new king in town has arrived\n<a href="https://github.com/bombela/backward-cpp" rel="noreferrer">https://github.com/bombela/backward-cpp</a></p>\n\n<p>1 header to place in your code and 1 library to install.</p>\n\n<p>Personally I call it using this function</p>\n\n<pre><code>#include "backward.hpp"\nvoid stacker() {\n\nusing namespace backward;\nStackTrace st;\n\n\nst.load_here(99); //Limit the number of trace depth to 99\nst.skip_n_firsts(3);//This will skip some backward internal function from the trace\n\nPrinter p;\np.snippet = true;\np.object = true;\np.color = true;\np.address = true;\np.print(st, stderr);\n}\n</code></pre>\n'}, {'answer_id': 49050274, 'author': 'IInspectable', 'author_id': 1889329, 'author_profile': 'https://Stackoverflow.com/users/1889329', 'pm_score': 3, 'selected': False, 'text': '<p>As a Windows-only solution, you can get the equivalent of a stack trace (with much, much more information) using <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/bb513641.aspx" rel="nofollow noreferrer">Windows Error Reporting</a>. With just a few registry entries, it can be set up to <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/bb787181.aspx" rel="nofollow noreferrer">collect user-mode dumps</a>:</p>\n<blockquote>\n<p>Starting with Windows Server 2008 and Windows Vista with Service Pack 1 (SP1), Windows Error Reporting (WER) can be configured so that full user-mode dumps are collected and stored locally after a user-mode application crashes. [...]</p>\n<p>This feature is not enabled by default. Enabling the feature requires administrator privileges. To enable and configure the feature, use the following registry values under the <strong>HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\Windows Error Reporting\\LocalDumps</strong> key.</p>\n</blockquote>\n<p>You can set the registry entries from your installer, which has the required privileges.</p>\n<p>Creating a user-mode dump has the following advantages over generating a stack trace on the client:</p>\n<ul>\n<li>It\'s already implemented in the system. You can either use WER as outlined above, or call <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms680360.aspx" rel="nofollow noreferrer">MiniDumpWriteDump</a> yourself, if you need more fine-grained control over the amount of information to dump. (Make sure to call it from a different process.)</li>\n<li><strong>Way</strong> more complete than a stack trace. Among others it can contain local variables, function arguments, stacks for other threads, loaded modules, and so on. The amount of data (and consequently size) is highly customizable.</li>\n<li>No need to ship debug symbols. This both drastically decreases the size of your deployment, as well as makes it harder to reverse-engineer your application.</li>\n<li>Largely independent of the compiler you use. Using WER does not even require any code. Either way, having a way to get a symbol database (PDB) is <em>very</em> useful for offline analysis. I believe GCC can either generate PDB\'s, or there are tools to convert the symbol database to the PDB format.</li>\n</ul>\n<p>Take note, that WER can only be triggered by an application crash (i.e. the system terminating a process due to an unhandled exception). <code>MiniDumpWriteDump</code> can be called at any time. This may be helpful if you need to dump the current state to diagnose issues other than a crash.</p>\n<p>Mandatory reading, if you want to evaluate the applicability of mini dumps:</p>\n<ul>\n<li><a href="http://www.debuginfo.com/articles/effminidumps.html" rel="nofollow noreferrer">Effective minidumps</a></li>\n<li><a href="http://www.debuginfo.com/articles/effminidumps2.html" rel="nofollow noreferrer">Effective minidumps (Part 2)</a></li>\n</ul>\n'}, {'answer_id': 54427899, 'author': 'baziorek', 'author_id': 1350091, 'author_profile': 'https://Stackoverflow.com/users/1350091', 'pm_score': 4, 'selected': False, 'text': '<p>It looks like in one of last c++ boost version appeared library to provide exactly what You want, probably the code would be multiplatform.\nIt is <a href="https://www.boost.org/doc/libs/1_69_0/doc/html/stacktrace.html" rel="noreferrer">boost::stacktrace</a>, which You can use like <a href="https://www.boost.org/doc/libs/1_69_0/doc/html/stacktrace/getting_started.html" rel="noreferrer">as in boost sample</a>:</p>\n\n<pre><code>#include &lt;filesystem&gt;\n#include &lt;sstream&gt;\n#include &lt;fstream&gt;\n#include &lt;signal.h&gt;     // ::signal, ::raise\n#include &lt;boost/stacktrace.hpp&gt;\n\nconst char* backtraceFileName = "./backtraceFile.dump";\n\nvoid signalHandler(int)\n{\n    ::signal(SIGSEGV, SIG_DFL);\n    ::signal(SIGABRT, SIG_DFL);\n    boost::stacktrace::safe_dump_to(backtraceFileName);\n    ::raise(SIGABRT);\n}\n\nvoid sendReport()\n{\n    if (std::filesystem::exists(backtraceFileName))\n    {\n        std::ifstream file(backtraceFileName);\n\n        auto st = boost::stacktrace::stacktrace::from_dump(file);\n        std::ostringstream backtraceStream;\n        backtraceStream &lt;&lt; st &lt;&lt; std::endl;\n\n        // sending the code from st\n\n        file.close();\n        std::filesystem::remove(backtraceFileName);\n    }\n}\n\nint main()\n{\n    ::signal(SIGSEGV, signalHandler);\n    ::signal(SIGABRT, signalHandler);\n\n    sendReport();\n    // ... rest of code\n}\n</code></pre>\n\n<p>In Linux You compile the code above:</p>\n\n<pre><code>g++ --std=c++17 file.cpp -lstdc++fs -lboost_stacktrace_backtrace -ldl -lbacktrace\n</code></pre>\n\n<p>Example backtrace copied from <a href="https://www.boost.org/doc/libs/1_69_0/doc/html/stacktrace/getting_started.html" rel="noreferrer">boost documentation</a>:</p>\n\n<pre><code>0# bar(int) at /path/to/source/file.cpp:70\n1# bar(int) at /path/to/source/file.cpp:70\n2# bar(int) at /path/to/source/file.cpp:70\n3# bar(int) at /path/to/source/file.cpp:70\n4# main at /path/to/main.cpp:93\n5# __libc_start_main in /lib/x86_64-linux-gnu/libc.so.6\n6# _start\n</code></pre>\n'}, {'answer_id': 55626241, 'author': 'Geoffrey', 'author_id': 637874, 'author_profile': 'https://Stackoverflow.com/users/637874', 'pm_score': 2, 'selected': False, 'text': '<p>If you still want to go it alone as I did you can link against <code>bfd</code> and avoid using <code>addr2line</code> as I have done here:</p>\n<p><a href="https://github.com/gnif/LookingGlass/blob/master/common/src/platform/linux/crash.c" rel="nofollow noreferrer">https://github.com/gnif/LookingGlass/blob/master/common/src/platform/linux/crash.c</a></p>\n<p>This produces the output:</p>\n<pre><code>[E]        crash.linux.c:170  | crit_err_hdlr                  | ==== FATAL CRASH (a12-151-g28b12c85f4+1) ====\n[E]        crash.linux.c:171  | crit_err_hdlr                  | signal 11 (Segmentation fault), address is (nil)\n[E]        crash.linux.c:194  | crit_err_hdlr                  | [trace]: (0) /home/geoff/Projects/LookingGlass/client/src/main.c:936 (register_key_binds)\n[E]        crash.linux.c:194  | crit_err_hdlr                  | [trace]: (1) /home/geoff/Projects/LookingGlass/client/src/main.c:1069 (run)\n[E]        crash.linux.c:194  | crit_err_hdlr                  | [trace]: (2) /home/geoff/Projects/LookingGlass/client/src/main.c:1314 (main)\n[E]        crash.linux.c:199  | crit_err_hdlr                  | [trace]: (3) /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xeb) [0x7f8aa65f809b]\n[E]        crash.linux.c:199  | crit_err_hdlr                  | [trace]: (4) ./looking-glass-client(_start+0x2a) [0x55c70fc4aeca]\n</code></pre>\n'}, {'answer_id': 71143028, 'author': 'Oleksandr Kozlov', 'author_id': 2091463, 'author_profile': 'https://Stackoverflow.com/users/2091463', 'pm_score': 1, 'selected': False, 'text': "<pre><code>gdb -ex 'set confirm off' -ex r -ex bt -ex q &lt;my-program&gt;\n</code></pre>\n"}, {'answer_id': 72486459, 'author': 'Graham Toal', 'author_id': 210830, 'author_profile': 'https://Stackoverflow.com/users/210830', 'pm_score': 0, 'selected': False, 'text': '<p>You are probably not going to like this - all I can say in its favour is that it works for me, and I have similar but not identical requirements: I am writing a compiler/transpiler for a 1970\'s Algol-like language which uses C as it\'s output and then compiles the C so that as far as the user is concerned, they\'re generally not aware of C being involved, so although you might call it a transpiler, it\'s effectively a compiler that uses C as it\'s intermediate code.  The language being compiled has a history of providing good diagnostics and a full backtrace in the original native compilers.  I\'ve been able to find gcc compiler flags and libraries etc that allow me to trap most of the runtime errors that the original compilers did (although with one glaring exception - unassigned variable trapping).  When a runtime error occurs (eg arithmetic overflow, divide by zero, array index out of bounds, etc) the original compilers output a backtrace to the console listing all variables in the stack frames of every active procedure call.  I struggled to get this effect in C, but eventually did so with what can only be described as a hack... When the program is invoked, the wrapper that supplies the C &quot;main&quot; looks at its argv, and if a special option is not present, it restarts itself under gdb with an altered argv containing both gdb options and the \'magic\' option string for the program itself.  This restarted version then hides those strings from the user\'s code by restoring the original arguments before calling the main block of the code written in our language.  When an error occurs (as long as it is not one explicitly trapped within the program by user code), it exits to gdb which prints the required backtrace.</p>\n<p>Keys lines of code in the startup sequence include:</p>\n<pre><code>  if ((argc &gt;= 1) &amp;&amp; (strcmp(origargv[argc-1], &quot;--restarting-under-gdb&quot;)) != 0) {\n    // initial invocation\n    // the &quot;--restarting-under-gdb&quot; option is how the copy running under gdb knows\n    // not to start another gdb process.\n</code></pre>\n<p>and</p>\n<pre><code>  char *gdb [] = {\n    &quot;/usr/bin/gdb&quot;, &quot;-q&quot;, &quot;-batch&quot;, &quot;-nx&quot;, &quot;-nh&quot;, &quot;-return-child-result&quot;,\n    &quot;-ex&quot;, &quot;run&quot;,\n    &quot;-ex&quot;, &quot;bt full&quot;,\n    &quot;--args&quot;\n  };\n</code></pre>\n<p>The original arguments are appended to the gdb options above.  That should be enough of a hint for you to do something similar for your own system.\nI did look at other library-supported backtrace options (eg libbacktrace,\n<a href="https://codingrelic.geekhold.com/2010/09/gcc-function-instrumentation.html" rel="nofollow noreferrer">https://codingrelic.geekhold.com/2010/09/gcc-function-instrumentation.html</a>, etc) but they only output the procedure call stack, not the local variables.  However if anyone knows of any cleaner mechanism to get a similar effect, do please let us know. The main downside to this is that the variables are printed in C syntax, not the syntax of the language the user writes in.  And (until I add suitable #line directives <em>on every generated line of C :-(</em>) the backtrace lists the C source file and line numbers.</p>\n<p>G\nPS The gcc compile options I use are:</p>\n<pre><code> GCCOPTS=&quot; -Wall -Wno-return-type -Wno-comment -g -fsanitize=undefined\n -fsanitize-undefined-trap-on-error -fno-sanitize-recover=all -frecord-gcc-switches\n -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -ftrapv\n -grecord-gcc-switches -O0 -ggdb3 &quot;\n</code></pre>\n'}, {'answer_id': 74549444, 'author': 'Ciro Santilli OurBigBook.com', 'author_id': 895245, 'author_profile': 'https://Stackoverflow.com/users/895245', 'pm_score': 0, 'selected': False, 'text': '<p><strong>My best async signal safe attempt so far</strong></p>\n<p>Let me know if it is not actually safe. I could not yet find a way to show line numbers.</p>\n<pre><code>#include &lt;execinfo.h&gt;\n#include &lt;signal.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;unistd.h&gt;\n\n#define TRACE_MAX 1024\n\nvoid handler(int sig) {\n    (void)sig;\n    void *array[TRACE_MAX];\n    size_t size;\n    const char msg[] = &quot;failed with a signal\\n&quot;;\n\n    size = backtrace(array, TRACE_MAX);\n    write(STDERR_FILENO, msg, sizeof(msg));\n    backtrace_symbols_fd(array, size, STDERR_FILENO);\n    _Exit(1);\n}\n\nvoid my_func_2(void) {\n    *((int*)0) = 1;\n}\n\nvoid my_func_1(double f) {\n    (void)f;\n    my_func_2();\n}\n\nvoid my_func_1(int i) {\n    (void)i;\n    my_func_2();\n}\n\nint main() {\n    /* Make a dummy call to `backtrace` to load libgcc because man backrace says:\n     *    *  backtrace() and backtrace_symbols_fd() don\'t call malloc() explicitly, but they are part of libgcc, which gets loaded dynamically when first used.  Dynamic loading usually triggers a call to mal‐\n     *       loc(3).  If you need certain calls to these two functions to not allocate memory (in signal handlers, for example), you need to make sure libgcc is loaded beforehand.\n     */\n    void *dummy[1];\n    backtrace(dummy, 1);\n    signal(SIGSEGV, handler);\n\n    my_func_1(1);\n}\n</code></pre>\n<p>Compile and run:</p>\n<pre><code>g++ -ggdb3 -O2 -std=c++11 -Wall -Wextra -pedantic -rdynamic -o stacktrace_on_signal_safe.out stacktrace_on_signal_safe.cpp\n./stacktrace_on_signal_safe.out\n</code></pre>\n<p><code>-rdynamic</code> is needed to get the function names:</p>\n<pre><code>failed with a signal\n./stacktrace_on_signal_safe.out(_Z7handleri+0x6e)[0x56239398928e]\n/lib/x86_64-linux-gnu/libc.so.6(+0x42520)[0x7f04b1459520]\n./stacktrace_on_signal_safe.out(main+0x38)[0x562393989118]\n/lib/x86_64-linux-gnu/libc.so.6(+0x29d90)[0x7f04b1440d90]\n/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80)[0x7f04b1440e40]\n./stacktrace_on_signal_safe.out(_start+0x25)[0x562393989155]\n</code></pre>\n<p>We can then pipe it to <code>c++filt</code> to demangle:</p>\n<pre><code>./stacktrace_on_signal_safe.out |&amp; c++filt\n</code></pre>\n<p>giving:</p>\n<pre><code>failed with a signal\n/stacktrace_on_signal_safe.out(handler(int)+0x6e)[0x55b6df43f28e]\n/lib/x86_64-linux-gnu/libc.so.6(+0x42520)[0x7f40d4167520]\n./stacktrace_on_signal_safe.out(main+0x38)[0x55b6df43f118]\n/lib/x86_64-linux-gnu/libc.so.6(+0x29d90)[0x7f40d414ed90]\n/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80)[0x7f40d414ee40]\n./stacktrace_on_signal_safe.out(_start+0x25)[0x55b6df43f155]\n</code></pre>\n<p>Several levels are missing due to optimizations, with <code>-O0</code> we get a fuller:</p>\n<pre><code>/stacktrace_on_signal_safe.out(handler(int)+0x76)[0x55d39b68325f]\n/lib/x86_64-linux-gnu/libc.so.6(+0x42520)[0x7f4d8ffdd520]\n./stacktrace_on_signal_safe.out(my_func_2()+0xd)[0x55d39b6832bb]\n./stacktrace_on_signal_safe.out(my_func_1(int)+0x14)[0x55d39b6832f1]\n./stacktrace_on_signal_safe.out(main+0x4a)[0x55d39b68333e]\n/lib/x86_64-linux-gnu/libc.so.6(+0x29d90)[0x7f4d8ffc4d90]\n/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80)[0x7f4d8ffc4e40]\n./stacktrace_on_signal_safe.out(_start+0x25)[0x55d39b683125]\n</code></pre>\n<p>Line numbers are not present, but we can get them with <code>addr2line</code>. This requires building without <code>-rdynamic</code>:</p>\n<pre><code>g++ -ggdb3 -O0 -std=c++23 -Wall -Wextra -pedantic -o stacktrace_on_signal_safe.out stacktrace_on_signal_safe.cpp\n./stacktrace_on_signal_safe.out |&amp; sed -r \'s/.*\\(//;s/\\).*//\' | addr2line -C -e stacktrace_on_signal_safe.out -f\n</code></pre>\n<p>producing:</p>\n<pre><code>??\n??:0\nhandler(int)\n/home/ciro/stacktrace_on_signal_safe.cpp:14\n??\n??:0\nmy_func_2()\n/home/ciro/stacktrace_on_signal_safe.cpp:22\nmy_func_1(i\n/home/ciro/stacktrace_on_signal_safe.cpp:33\nmain\n/home/ciro/stacktrace_on_signal_safe.cpp:45\n??\n??:0\n??\n??:0\n_start\n??:?\n</code></pre>\n<p><code>awk</code> parses the <code>+&lt;addr&gt;</code> numbers out o the non <code>-rdynamic</code> output:</p>\n<pre><code>./stacktrace_on_signal_safe.out(+0x125f)[0x55984828825f]\n/lib/x86_64-linux-gnu/libc.so.6(+0x42520)[0x7f8644a1e520]\n./stacktrace_on_signal_safe.out(+0x12bb)[0x5598482882bb]\n./stacktrace_on_signal_safe.out(+0x12f1)[0x5598482882f1]\n./stacktrace_on_signal_safe.out(+0x133e)[0x55984828833e]\n/lib/x86_64-linux-gnu/libc.so.6(+0x29d90)[0x7f8644a05d90]\n/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80)[0x7f8644a05e40]\n./stacktrace_on_signal_safe.out(+0x1125)[0x559848288125]\n</code></pre>\n<p>If you also want to print the actual signal number to stdout, here\'s an async signal safe implementation int to string: <a href="https://stackoverflow.com/questions/14573000/print-int-from-signal-handler-using-write-or-async-safe-functions/52111436#52111436">Print int from signal handler using write or async-safe functions</a> since <code>printf</code> is not.</p>\n<p>Tested on Ubuntu 22.04.</p>\n<p><strong>C++23 <code>&lt;stacktrace&gt;</code></strong></p>\n<p>Like many other answers, this section ignores async signal safe aspects of the problem, which could lead your code to deadlock on crash, which could be serious. We can only hope one day the C++ standard will add a <code>boost::stacktrace::safe_dump_to</code>-like function to solve this once and for all.</p>\n<p>This will be the generally superior C++ stacktrace option moving forward as mentioned at: <a href="https://stackoverflow.com/questions/3899870/print-call-stack-in-c-or-c/54365144#54365144">print call stack in C or C++</a> as it shows line numbers and does demangling for us automatically.</p>\n<p>stacktrace_on_signal.cpp</p>\n<pre><code>#include &lt;stacktrace&gt;\n#include &lt;iostream&gt;\n\n#include &lt;signal.h&gt;\n#include &lt;stdlib.h&gt;\n#include &lt;unistd.h&gt;\n\nvoid handler(int sig) {\n    (void)sig;\n    /* De-register this signal in the hope of avoiding infinite loops\n     * if asyns signal unsafe things fail later on. But can likely still deadlock. */\n    signal(sig, SIG_DFL);\n    // std::stacktrace::current\n    std::cout &lt;&lt; std::stacktrace::current();\n    // C99 async signal safe version of exit().\n    _Exit(1);\n}\n\nvoid my_func_2(void) {\n    *((int*)0) = 1;\n}\n\nvoid my_func_1(double f) {\n    (void)f;\n    my_func_2();\n}\n\nvoid my_func_1(int i) {\n    (void)i;\n    my_func_2();\n}\n\nint main() {\n    signal(SIGSEGV, handler);\n    my_func_1(1);\n}\n</code></pre>\n<p>Compile and run:</p>\n<pre><code>g++ -ggdb3 -O2 -std=c++23 -Wall -Wextra -pedantic -o stacktrace_on_signal.out stacktrace_on_signal.cpp -lstdc++_libbacktrace\n./stacktrace_on_signal.out\n</code></pre>\n<p>Output on GCC 12.1 compiled from source, Ubuntu 22.04:</p>\n<pre><code>   0# handler(int) at /home/ciro/stacktrace_on_signal.cpp:11\n   1#      at :0\n   2# my_func_2() at /home/ciro/stacktrace_on_signal.cpp:16\n   3#      at :0\n   4#      at :0\n   5#      at :0\n   6#\n</code></pre>\n<p>I think it missed <code>my_func_1</code> due to optimization being turned on, and there is in general nothing we can do about that AFAIK. With <code>-O0</code> instead it is better:</p>\n<pre><code>   0# handler(int) at /home/ciro/stacktrace_on_signal.cpp:11\n   1#      at :0\n   2# my_func_2() at /home/ciro/stacktrace_on_signal.cpp:16\n   3# my_func_1(int) at /home/ciro/stacktrace_on_signal.cpp:26\n   4#      at /home/ciro/stacktrace_on_signal.cpp:31\n   5#      at :0\n   6#      at :0\n   7#      at :0\n   8#\n</code></pre>\n<p>but not sure why <code>main</code> didn\'t show up there.</p>\n<p><strong><code>backtrace_simple</code></strong></p>\n<p><a href="https://github.com/gcc-mirror/gcc/blob/releases/gcc-12.1.0/libstdc%2B%2B-v3/src/libbacktrace/backtrace-supported.h.in#L45" rel="nofollow noreferrer">https://github.com/gcc-mirror/gcc/blob/releases/gcc-12.1.0/libstdc%2B%2B-v3/src/libbacktrace/backtrace-supported.h.in#L45</a> mentions that <code>backtrace_simple</code> is safe:</p>\n<pre><code>/* BACKTRACE_USES_MALLOC will be #define\'d as 1 if the backtrace\n   library will call malloc as it works, 0 if it will call mmap\n   instead.  This may be used to determine whether it is safe to call\n   the backtrace functions from a signal handler.  In general this\n   only applies to calls like backtrace and backtrace_pcinfo.  It does\n   not apply to backtrace_simple, which never calls malloc.  It does\n   not apply to backtrace_print, which always calls fprintf and\n   therefore malloc.  */\n</code></pre>\n<p>but it does not appear very convenient for usage, mostly an internal tool.</p>\n<p><strong><code>std::basic_stacktrace</code></strong></p>\n<p>This is what <code>std::stacktrace</code> is based on according to: <a href="https://en.cppreference.com/w/cpp/utility/basic_stacktrace" rel="nofollow noreferrer">https://en.cppreference.com/w/cpp/utility/basic_stacktrace</a></p>\n<p>It has an allocator parameter which cppreference describes as:</p>\n<blockquote>\n<p>Support for custom allocators is provided for using basic_stacktrace on a hot path or in embedded environments. Users can allocate stacktrace_entry objects on the stack or in some other place, where appropriate.</p>\n</blockquote>\n<p>so I wonder if <code>basic_stacktrace</code> is itself async signal safe, and if it wouldn\'t be possible to make a version of <code>std::stacktrace</code> that is also with a custom allocator, e.g. either something that:</p>\n<ul>\n<li>writes to a file on disk like <code>boost::stacktrace::safe_dump_to</code></li>\n<li>or writes to some pre-alocated stack buffer with some maximum size</li>\n</ul>\n<p><a href="https://apolukhin.github.io/papers/stacktrace_r1.html" rel="nofollow noreferrer">https://apolukhin.github.io/papers/stacktrace_r1.html</a> might be the proposal that got in, mentions:</p>\n<blockquote>\n<p>Note about signal safety: this proposal does not attempt to provide a signal-safe solution for capturing and decoding stacktraces. Such functionality currently is not implementable on some of the popular platforms. However, the paper attempts to provide extensible solution, that may be made signal safe some day by providing a signal safe allocator and changing the stacktrace implementation details.</p>\n</blockquote>\n<p><strong>Just getting the core dump instead?</strong></p>\n<p>The core dump allows you to inspect memory with GDB: <a href="https://stackoverflow.com/questions/8305866/how-do-i-analyze-a-programs-core-dump-file-with-gdb-when-it-has-command-line-pa/54943610#54943610">How do I analyze a program&#39;s core dump file with GDB when it has command-line parameters?</a> so it is more powerful than just having the trace.</p>\n<p>Just make sure you enable it properly, notably on Ubuntu 22.04 you need:</p>\n<pre><code>echo \'core\' | sudo tee /proc/sys/kernel/core_pattern\n</code></pre>\n<p>or to learn to use apport, see also: <a href="https://askubuntu.com/questions/1349047/where-do-i-find-core-dump-files-and-how-do-i-view-and-analyze-the-backtrace-st/1442665#1442665">https://askubuntu.com/questions/1349047/where-do-i-find-core-dump-files-and-how-do-i-view-and-analyze-the-backtrace-st/1442665#1442665</a></p>\n'}]
['https://Stackoverflow.com/questions/77005', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/13676/']