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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
#include "debug.h"
#ifdef DEBUG_ENABLED
#include <map>
#include <fstream>
#include <unistd.h> // for the `write' method
int offset = 0;
std::map<void *, int> ptrs;
#define PRINT_INC(x) { \
char buf[128]; \
std::sprintf(buf, "%d: %p: %s", ++offset, ptr, x); \
write(1, buf, std::strlen(buf)); \
}
#define PRINT_DEC(x) { \
char buf[128]; \
std::sprintf(buf, "%d: %p: %s", --offset, ptr, x); \
write(1, buf, std::strlen(buf)); \
}
void * operator new(std::size_t size) throw (std::bad_alloc) {
void * ptr = std::malloc(size);
#if 0 // jww (2007-04-19): these don't work with boost::regex
if (DEBUG("debug.alloc")) {
PRINT_INC("void * operator new(std::size_t size) throw (std::bad_alloc)\n");
}
#endif
return ptr;
}
void * operator new[](std::size_t size) throw (std::bad_alloc) {
void * ptr = std::malloc(size);
#if 0
if (DEBUG("debug.alloc")) {
PRINT_INC("void * operator new[](std::size_t) throw (std::bad_alloc)\n");
}
#endif
return ptr;
}
void * operator new(std::size_t size, const std::nothrow_t&) throw() {
void * ptr = std::malloc(size);
#if 0
if (DEBUG("debug.alloc")) {
PRINT_INC("void * operator new(std::size_t size, const std::nothrow_t&) throw()\n");
}
#endif
return ptr;
}
void * operator new[](std::size_t size, const std::nothrow_t&) throw() {
void * ptr = std::malloc(size);
#if 0
if (DEBUG("debug.alloc")) {
PRINT_INC("void * operator new[](std::size_t size, const std::nothrow_t&) throw()\n");
}
#endif
return ptr;
}
void operator delete(void * ptr) throw() {
#if 0
if (DEBUG("debug.alloc")) {
PRINT_DEC("void operator delete(void * ptr) throw()\n");
}
#endif
std::free(ptr);
}
void operator delete[](void * ptr) throw() {
#if 0
if (DEBUG("debug.alloc")) {
PRINT_DEC("void operator delete[](void * ptr) throw()\n");
}
#endif
std::free(ptr);
}
void operator delete(void * ptr, const std::nothrow_t&) throw() {
#if 0
if (DEBUG("debug.alloc")) {
PRINT_DEC("void operator delete(void * ptr, const std::nothrow_t&) throw()\n");
}
#endif
std::free(ptr);
}
void operator delete[](void * ptr, const std::nothrow_t&) throw() {
#if 0
if (DEBUG("debug.alloc")) {
PRINT_DEC("void operator delete[](void * ptr, const std::nothrow_t&) throw()\n");
}
#endif
std::free(ptr);
}
std::ostream * _debug_stream = &std::cerr;
bool _free_debug_stream = false;
bool _debug_active(const char * const cls) {
if (char * debug = std::getenv("DEBUG_CLASS")) {
return boost::regex_match(cls, boost::regex(debug));
}
return false;
}
static struct init_streams {
init_streams() {
// If debugging is enabled and DEBUG_FILE is set, all debugging
// output goes to that file.
if (const char * p = std::getenv("DEBUG_FILE")) {
_debug_stream = new std::ofstream(p);
_free_debug_stream = true;
}
}
~init_streams() {
if (_free_debug_stream && _debug_stream) {
delete _debug_stream;
_debug_stream = NULL;
}
}
} _debug_init;
#endif // DEBUG_ENABLED
#if DEBUG_LEVEL >= BETA
#include <string>
void debug_assert(const std::string& reason,
const std::string& file,
unsigned long line)
{
throw new fatal_assert(reason, new file_context(file, line));
}
#endif
|