3 * Copyright (c) 1998-2002
6 * Permission to use, copy, modify, distribute and sell this software
7 * and its documentation for any purpose is hereby granted without fee,
8 * provided that the above copyright notice appear in all copies and
9 * that both that copyright notice and this permission notice appear
10 * in supporting documentation. Dr John Maddock makes no representations
11 * about the suitability of this software for any purpose.
12 * It is provided "as is" without express or implied warranty.
17 * LOCATION: see http://www.boost.org for most recent version.
18 * FILE: regex_debug.cpp
19 * VERSION: see <boost/version.hpp>
20 * DESCRIPTION: Misc. debugging helpers.
24 #define BOOST_REGEX_SOURCE
26 #include <boost/regex/config.hpp>
28 #ifdef BOOST_REGEX_DEBUG
34 #include <boost/regex/detail/regex_raw_buffer.hpp>
35 #include <boost/regex.hpp>
37 #ifndef BOOST_RE_OLD_IOSTREAM
43 namespace boost { namespace re_detail {
44 std::ostream& operator<<(std::ostream& s, syntax_element_type x)
46 return s << static_cast<unsigned long>(x);
48 }} // namespace boost::re_detail
54 char guard_pattern[32]
55 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
56 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, };
59 static const int guard_size = 32;
61 bool check_pattern(void* p)
63 return p ? memcmp(p, guard_pattern, guard_size) : 0;
66 inline unsigned maxi(unsigned i, unsigned j)
71 unsigned int allocated = 0;
82 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_DELAY_FREE_MEM_DF|_CRTDBG_LEAK_CHECK_DF);
93 void* get_mem(size_t n)
96 char* p = (char*)malloc(n + guard_size * 2 + maxi(sizeof(int) + sizeof(void*), boost::re_detail::padding_size) + boost::re_detail::padding_size);
98 p = (char*)((std::ptrdiff_t)(p + boost::re_detail::padding_mask) & ~boost::re_detail::padding_mask);
99 std::memcpy(p + maxi(sizeof(int) + sizeof(void*), boost::re_detail::padding_size), guard_pattern, guard_size);
100 std::memcpy(p + maxi(sizeof(int) + sizeof(void*), boost::re_detail::padding_size) + guard_size + n, guard_pattern, guard_size);
102 *(void**)(p + sizeof(int)) = base;
103 return p + guard_size + maxi(sizeof(int) + sizeof(void*), boost::re_detail::padding_size);
106 void free_mem(void* b)
111 p -= (guard_size + maxi(sizeof(int) + sizeof(void*), boost::re_detail::padding_size));
112 if(check_pattern(p + maxi(sizeof(int) + sizeof(void*), boost::re_detail::padding_size)) || check_pattern(p + maxi(sizeof(int) + sizeof(void*), boost::re_detail::padding_size) + guard_size + *(int*)p))
114 cerr << "Error: freed memory has been written past end..." << endl;
116 free(*(void**)(p + sizeof(int)));
123 void* operator new(size_t n)
128 void* operator new[](size_t n)
133 void operator delete(void* p)
138 void operator delete[](void* p)
148 std::set<debug_guard*, std::less<debug_guard*> >* patterns = 0;
150 int pattern_count = 0;
152 void check_patterns(const char* f, int l)
156 std::set<debug_guard*, std::less<debug_guard*> >::iterator i, j;
157 i = patterns->begin();
161 if(check_pattern((void*)(*i)->g1) || check_pattern((*i)->g2) || check_pattern((void*)(*i)->pc) || check_pattern((*i)->pnc))
163 cerr << "Error: static memory corruption at " << hex << *i << dec << " in " << (*i)->file << "@" << (*i)->line << " called from " << f << "@" << l << endl;
170 debug_guard::debug_guard(const char* f, int l, const char* p1, char* p2)
172 if(++pattern_count == 1)
173 patterns = new std::set<debug_guard*, std::less<debug_guard*> >;
176 std::memcpy(g1, guard_pattern, guard_size);
177 std::memcpy(g2, guard_pattern, guard_size);
187 std::memcpy(pnc, guard_pattern, guard_size);
191 patterns->insert(this);
194 debug_guard::~debug_guard()
196 check_patterns(file, line);
197 if(check_pattern(g1) || check_pattern(g2))
199 cerr << "Error: memory corruption " << file << "@" << line << endl;
201 patterns->erase(this);
202 if(--pattern_count == 0)
209 } // namespace re_detail