File: LeakCheck.h

package info (click to toggle)
stlport4.6 4.6.2-7
  • links: PTS, VCS
  • area: main
  • in suites: squeeze, wheezy
  • size: 7,056 kB
  • ctags: 16,390
  • sloc: ansic: 46,190; cpp: 18,805; sh: 266; asm: 93; perl: 58; makefile: 10
file content (219 lines) | stat: -rw-r--r-- 7,420 bytes parent folder | download | duplicates (5)
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
/*
 * Copyright (c) 1997
 * Mark of the Unicorn, Inc.
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  Mark of the Unicorn makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 */
/***********************************************************************************
	LeakCheck.h
	
		SUMMARY: A suite of template functions for verifying the behavior of
			operations in the presence of exceptions. Requires that the operations
			be written so that each operation that could cause an exception causes
			simulate_possible_failure() to be called (see "nc_alloc.h").
		
***********************************************************************************/
#if !INCLUDED_MOTU_LeakCheck
#define INCLUDED_MOTU_LeakCheck 1

# include "Prefix.h"

# include "nc_alloc.h"

# if defined (EH_NEW_HEADERS)
#  include <cstdio>
#  include <cassert>
#  include <iterator>
# else
#  include <stdio.h>
#  include <assert.h>
#  include <iterator.h>
# endif

# if defined (EH_NEW_IOSTREAMS)
#  include <iostream>
# else
#  include <iostream.h>
# endif

EH_BEGIN_NAMESPACE

template <class T1, class T2>
inline ostream& operator << ( 
ostream& s, 
const pair <T1, T2>& p) {
    return s<<'['<<p.first<<":"<<p.second<<']';
}
EH_END_NAMESPACE

/*===================================================================================
	CheckInvariant

	EFFECTS:  Generalized function to check an invariant on a container. Specialize
		this for particular containers if such a check is available.
====================================================================================*/
template <class C>
void CheckInvariant(const C&)
{
}

/*===================================================================================
	WeakCheck

	EFFECTS: Given a value and an operation, repeatedly applies the operation to a
		copy of the value triggering the nth possible exception, where n increments
		with each repetition until no exception is thrown or max_iters is reached.
		Reports any detected memory leaks and checks any invariant defined for the
		value type whether the operation succeeds or fails.
====================================================================================*/
template <class Value, class Operation>
void WeakCheck( const Value& v, const Operation& op, long max_iters = 2000000 )
{
    bool succeeded = false;
    bool failed = false;
    gTestController.SetCurrentTestCategory("weak");
    for ( long count = 0; !succeeded && !failed && count < max_iters; count++ )
    {
        gTestController.BeginLeakDetection();
        {
            Value dup = v;
# ifndef EH_NO_EXCEPTIONS
            try {
# endif
                gTestController.SetFailureCountdown(count);
                op( dup );
                succeeded = true;
# ifndef EH_NO_EXCEPTIONS
            }
            catch(...) {}	// Just try again.
# endif
            gTestController.CancelFailureCountdown();
            CheckInvariant(dup);
        }
        failed = gTestController.ReportLeaked();
        EH_ASSERT( !failed );
        
        if ( succeeded )
			gTestController.ReportSuccess(count);
    }
    EH_ASSERT( succeeded || failed );	// Make sure the count hasn't gone over
}

/*===================================================================================
	ConstCheck

	EFFECTS:  Similar to WeakCheck (above), but for operations which may not modify
		their arguments. The operation is performed on the value itself, and no
		invariant checking is performed. Leak checking still occurs.
====================================================================================*/
template <class Value, class Operation>
void ConstCheck( const Value& v, const Operation& op, long max_iters = 2000000 )
{
    bool succeeded = false;
    bool failed = false;
    gTestController.SetCurrentTestCategory("const");
    for ( long count = 0; !succeeded && !failed && count < max_iters; count++ )
    {
        gTestController.BeginLeakDetection();
        {
# ifndef EH_NO_EXCEPTIONS
            try {
# endif
                gTestController.SetFailureCountdown(count);
                op( v );
                succeeded = true;
# ifndef EH_NO_EXCEPTIONS
            }
            catch(...) {}	// Just try again.
# endif
            gTestController.CancelFailureCountdown();
        }
        failed = gTestController.ReportLeaked();
        EH_ASSERT( !failed );

        if ( succeeded )
			gTestController.ReportSuccess(count);
    }
    EH_ASSERT( succeeded || failed );	// Make sure the count hasn't gone over
}

/*===================================================================================
	StrongCheck

	EFFECTS:  Similar to WeakCheck (above), but additionally checks a component of
		the "strong guarantee": if the operation fails due to an exception, the
		value being operated on must be unchanged, as checked with operator==().
		
	CAVEATS: Note that this does not check everything required for the strong
		guarantee, which says that if an exception is thrown, the operation has no
		effects. Do do that we would have to check that no there were no side-effects
		on objects which are not part of v (e.g. iterator validity must be preserved).
		
====================================================================================*/
template <class Value, class Operation>
void StrongCheck( const Value& v, const Operation& op, long max_iters = 2000000 )
{
    bool succeeded = false;
    bool failed = false;
    gTestController.SetCurrentTestCategory("strong");
    for ( long count = 0; !succeeded && !failed && count < max_iters; count++ )
    {
        gTestController.BeginLeakDetection();

        {
            Value dup = v;
            {
# ifndef EH_NO_EXCEPTIONS
            try
# endif
			{
                gTestController.SetFailureCountdown(count);
                op( dup );
                succeeded = true;
                gTestController.CancelFailureCountdown();
			}
# ifndef EH_NO_EXCEPTIONS
            catch(...)
            {
                gTestController.CancelFailureCountdown();
                bool unchanged = dup == v;
                EH_ASSERT( unchanged );
                
                if ( !unchanged )
                {
#if 0
                    typedef typename Value::value_type value_type;
                    EH_STD::ostream_iterator<value_type> o(EH_STD::cerr, " ");
                    EH_STD::cerr<<"EH test FAILED:\nStrong guaranee failed !\n";
                    EH_STD::copy(dup.begin(), dup.end(), o);
                    EH_STD::cerr<<"\nOriginal is:\n";
                    EH_STD::copy(v.begin(), v.end(), o);
                    EH_STD::cerr<<EH_STD::endl;
#endif
                    failed = true;
                }
            }	// Just try again.
# endif
            CheckInvariant(v);
        }

        }

	bool leaked = gTestController.ReportLeaked();
	EH_ASSERT( !leaked );
	if ( leaked )
	  failed = true;
    
        if ( succeeded )
			gTestController.ReportSuccess(count);
    }
    EH_ASSERT( succeeded || failed );	// Make sure the count hasn't gone over
}

#endif // INCLUDED_MOTU_LeakCheck