-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStackTrace.h
More file actions
100 lines (85 loc) · 2.48 KB
/
StackTrace.h
File metadata and controls
100 lines (85 loc) · 2.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/** ======================================================================+
+ Copyright @2020-2021 Arjun Ray
+ Released under MIT License
+ see https://mit-license.org
+========================================================================*/
#pragma once
#include "CallStack.h"
#include <ostream>
#include <sstream>
#include <stdexcept>
namespace Utility
{
// SYmbolPrinter.
// Pretty-prints callstack entries.
//
class SymbolPrinter
{
public:
SymbolPrinter(std::ostream& os)
: os_(os)
, slot_(0)
{}
void operator() ( std::string const& symbol ) const
{
os_ << (slot_ < 10 ? " [" : "[") << slot_ << "] " << symbol << "\n";
++slot_;
}
private:
std::ostream& os_;
int mutable slot_;
};
// CallstackPrinter.
// Organizes pretty-printing of a GNU compiler callstack.
//
// Sample usage:
// (CallstackPrinter(std::cerr))( CallStack() );
// Or:
// CallStack(CallstackPrinter(std::cerr));
// Yes, both ways work!:-)
//
class CallstackPrinter
{
public:
CallstackPrinter(std::ostream& os)
: printer_(os)
{}
// could use a lambda instead
void operator() ( CallStack&& stack ) const { stack.for_each( *this ); }
void operator() ( CallStack const& stack ) const { stack.for_each( *this ); }
void operator() ( char* symbol ) const { printer_( SymbolAnalyser(symbol) ); }
private:
SymbolPrinter printer_;
};
// StackTrace.
// Holds a stack trace as a string.
//
class StackTrace
{
public:
explicit
StackTrace(char const* prefix = "Stack trace:\n")
: oss_(prefix, std::ostringstream::ate)
, printer_(oss_)
, stack_(printer_, 2)
{}
std::string const get() const { return oss_.str(); }
operator std::string const () const { return get(); }
private:
std::ostringstream oss_;
CallstackPrinter printer_;
CallStack stack_;
};
// TrapException.
// Capture stack trace as part of conversion of
// hardware trap (synchronous signal) to exception.
//
struct TrapException
: public std::runtime_error
{
explicit
TrapException(char const* prefix)
: std::runtime_error(StackTrace(prefix))
{}
};
} // namespace Utility