source: branches/profile/TEMPLATES/arb_backtrace.h

Last change on this file was 12276, checked in by westram, 10 years ago
  • added a bunch of arguments to CLI that allow to test various ways to terminate
  • exit from signal handler with exitcode≥128
  • arb_launcher knows about 3 types of exitcodes:
    • 0 = success
    • 1 = failure (no crash); no longer tell arb did crash in this case, fixing #538
    • else = crash
File size: 3.0 KB
Line 
1// ============================================================== //
2//                                                                //
3//   File      : arb_backtrace.h                                  //
4//   Purpose   :                                                  //
5//                                                                //
6//   Coded by Ralf Westram (coder@reallysoft.de) in August 2010   //
7//   Institute of Microbiology (Technical University Munich)      //
8//   http://www.arb-home.de/                                      //
9//                                                                //
10// ============================================================== //
11
12#ifndef ARB_BACKTRACE_H
13#define ARB_BACKTRACE_H
14
15#define MAX_BACKTRACE 66
16
17#ifndef _GLIBCXX_CSTDLIB
18#include <cstdlib>
19#endif
20#ifndef _GLIBCXX_CSTDIO
21#include <cstdio>
22#endif
23#ifndef _EXECINFO_H
24#include <execinfo.h>
25#endif
26#ifndef ARB_ASSERT_H
27#include <arb_assert.h>
28#endif
29#ifndef ARBTOOLS_H
30#include "arbtools.h"
31#endif
32
33#define ARB_CRASH_CODE(sig) (128+(sig))
34
35class BackTraceInfo : virtual Noncopyable {
36    void   **array;
37    size_t   size;
38
39public:
40
41    static bool& suppress() {
42        static bool suppress_ = false;
43        return suppress_;
44    }
45
46    explicit BackTraceInfo(size_t skipFramesAtBottom) {
47        void *tmp[MAX_BACKTRACE];
48        size = backtrace(tmp, MAX_BACKTRACE);
49
50        size_t wantedFrames = size-skipFramesAtBottom;
51
52        arb_assert(wantedFrames>0); // skipped more than all frames
53
54        size_t msize = wantedFrames*sizeof(*array);
55
56        array = (void**)malloc(msize);
57        // cppcheck-suppress arithOperationsOnVoidPointer (false positive: pointer-arithmetics on void** are completely standard compliant)
58        memcpy(array, tmp+skipFramesAtBottom, msize);
59
60        size = wantedFrames;
61    }
62    ~BackTraceInfo() { free(array); }
63
64    bool dump(FILE *out, const char *message) const {
65        // print out all the stack frames to 'out'
66        // return true on success.
67
68        if (fprintf(out, "\n-------------------- ARB-backtrace '%s':\n", message) < 0) return false;
69        fflush(out);
70        backtrace_symbols_fd(array, size, fileno(out));
71        if (size == MAX_BACKTRACE) fputs("[stack truncated to avoid deadlock]\n", out);
72        fputs("-------------------- End of backtrace\n", out);
73        return fflush(out) == 0;
74    }
75};
76
77inline void demangle_backtrace(const class BackTraceInfo& trace, FILE *out, const char *message) {
78    if (!BackTraceInfo::suppress()) {
79        static bool filtfailed = false;
80        if (!filtfailed) {
81            // @@@ Warning: this branch ignores parameter 'out'
82            FILE *filt = popen("/usr/bin/c++filt", "w");
83            if (filt) {
84                filtfailed   = !trace.dump(filt, message);
85                int exitcode = pclose(filt);
86                if (exitcode != 0 && !filtfailed) filtfailed = true;
87            }
88            else filtfailed = true;
89        }
90        if (filtfailed) trace.dump(out, message);
91    }
92}
93
94
95
96#else
97#error arb_backtrace.h included twice
98#endif // ARB_BACKTRACE_H
Note: See TracBrowser for help on using the repository browser.