source: tags/arb-6.0-rc1/TEMPLATES/arb_backtrace.h

Last change on this file was 10947, checked in by westram, 12 years ago
  • new cppcheck suppressions
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
33class BackTraceInfo : virtual Noncopyable {
34    void   **array;
35    size_t   size;
36
37public:
38
39    static bool& suppress() {
40        static bool suppress_ = false;
41        return suppress_;
42    }
43
44    explicit BackTraceInfo(size_t skipFramesAtBottom) {
45        void *tmp[MAX_BACKTRACE];
46        size = backtrace(tmp, MAX_BACKTRACE);
47
48        size_t wantedFrames = size-skipFramesAtBottom;
49
50        arb_assert(wantedFrames>0); // skipped more than all frames
51
52        size_t msize = wantedFrames*sizeof(*array);
53
54        array = (void**)malloc(msize);
55        // cppcheck-suppress arithOperationsOnVoidPointer (false positive: pointer-arithmetics on void** are completely standard compliant)
56        memcpy(array, tmp+skipFramesAtBottom, msize);
57
58        size = wantedFrames;
59    }
60    ~BackTraceInfo() { free(array); }
61
62    bool dump(FILE *out, const char *message) const {
63        // print out all the stack frames to 'out'
64        // return true on success.
65
66        if (fprintf(out, "\n-------------------- ARB-backtrace '%s':\n", message) < 0) return false;
67        fflush(out);
68        backtrace_symbols_fd(array, size, fileno(out));
69        if (size == MAX_BACKTRACE) fputs("[stack truncated to avoid deadlock]\n", out);
70        fputs("-------------------- End of backtrace\n", out);
71        return fflush(out) == 0;
72    }
73};
74
75inline void demangle_backtrace(const class BackTraceInfo& trace, FILE *out, const char *message) {
76    if (!BackTraceInfo::suppress()) {
77        static bool filtfailed = false;
78        if (!filtfailed) {
79            // @@@ Warning: this branch ignores parameter 'out'
80            FILE *filt = popen("/usr/bin/c++filt", "w");
81            if (filt) {
82                filtfailed   = !trace.dump(filt, message);
83                int exitcode = pclose(filt);
84                if (exitcode != 0 && !filtfailed) filtfailed = true;
85            }
86            else filtfailed = true;
87        }
88        if (filtfailed) trace.dump(out, message);
89    }
90}
91
92
93
94#else
95#error arb_backtrace.h included twice
96#endif // ARB_BACKTRACE_H
Note: See TracBrowser for help on using the repository browser.