ReactOS  0.4.14-dev-552-g2fad488
LeakCheck.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 1997
3  * Mark of the Unicorn, Inc.
4  *
5  * Permission to use, copy, modify, distribute and sell this software
6  * and its documentation for any purpose is hereby granted without fee,
7  * provided that the above copyright notice appear in all copies and
8  * that both that copyright notice and this permission notice appear
9  * in supporting documentation. Mark of the Unicorn makes no
10  * representations about the suitability of this software for any
11  * purpose. It is provided "as is" without express or implied warranty.
12  */
13 /***********************************************************************************
14  LeakCheck.h
15 
16  SUMMARY: A suite of template functions for verifying the behavior of
17  operations in the presence of exceptions. Requires that the operations
18  be written so that each operation that could cause an exception causes
19  simulate_possible_failure() to be called (see "nc_alloc.h").
20 
21 ***********************************************************************************/
22 #ifndef INCLUDED_MOTU_LeakCheck
23 #define INCLUDED_MOTU_LeakCheck 1
24 
25 #include "Prefix.h"
26 
27 #include "nc_alloc.h"
28 
29 #include <cstdio>
30 #include <cassert>
31 #include <iterator>
32 
33 #include <iostream>
34 
36 
37 template <class T1, class T2>
39 ostream& s,
40 const pair <T1, T2>& p) {
41  return s<<'['<<p.first<<":"<<p.second<<']';
42 }
44 
45 /*===================================================================================
46  CheckInvariant
47 
48  EFFECTS: Generalized function to check an invariant on a container. Specialize
49  this for particular containers if such a check is available.
50 ====================================================================================*/
51 template <class C>
52 void CheckInvariant(const C&)
53 {}
54 
55 /*===================================================================================
56  WeakCheck
57 
58  EFFECTS: Given a value and an operation, repeatedly applies the operation to a
59  copy of the value triggering the nth possible exception, where n increments
60  with each repetition until no exception is thrown or max_iters is reached.
61  Reports any detected memory leaks and checks any invariant defined for the
62  value type whether the operation succeeds or fails.
63 ====================================================================================*/
64 template <class Value, class Operation>
65 void WeakCheck(const Value& v, const Operation& op, long max_iters = 2000000) {
66  bool succeeded = false;
67  bool failed = false;
69  for (long count = 0; !succeeded && !failed && count < max_iters; ++count) {
71  {
72  Value dup = v;
73 #ifndef EH_NO_EXCEPTIONS
74  try {
75 #endif
77  op( dup );
78  succeeded = true;
79 #ifndef EH_NO_EXCEPTIONS
80  }
81  catch (...) {} // Just try again.
82 #endif
85  }
86  failed = gTestController.ReportLeaked();
87  EH_ASSERT( !failed );
88 
89  if ( succeeded )
91  }
92  EH_ASSERT( succeeded || failed ); // Make sure the count hasn't gone over
93 }
94 
95 /*===================================================================================
96  ConstCheck
97 
98  EFFECTS: Similar to WeakCheck (above), but for operations which may not modify
99  their arguments. The operation is performed on the value itself, and no
100  invariant checking is performed. Leak checking still occurs.
101 ====================================================================================*/
102 template <class Value, class Operation>
103 void ConstCheck(const Value& v, const Operation& op, long max_iters = 2000000) {
104  bool succeeded = false;
105  bool failed = false;
107  for (long count = 0; !succeeded && !failed && count < max_iters; ++count) {
109  {
110 #ifndef EH_NO_EXCEPTIONS
111  try {
112 #endif
114  op( v );
115  succeeded = true;
116 #ifndef EH_NO_EXCEPTIONS
117  }
118  catch(...) {} // Just try again.
119 # endif
121  }
122  failed = gTestController.ReportLeaked();
123  EH_ASSERT( !failed );
124 
125  if ( succeeded )
127  }
128  EH_ASSERT( succeeded || failed ); // Make sure the count hasn't gone over
129 }
130 
131 /*===================================================================================
132  StrongCheck
133 
134  EFFECTS: Similar to WeakCheck (above), but additionally checks a component of
135  the "strong guarantee": if the operation fails due to an exception, the
136  value being operated on must be unchanged, as checked with operator==().
137 
138  CAVEATS: Note that this does not check everything required for the strong
139  guarantee, which says that if an exception is thrown, the operation has no
140  effects. Do do that we would have to check that no there were no side-effects
141  on objects which are not part of v (e.g. iterator validity must be preserved).
142 
143 ====================================================================================*/
144 template <class Value, class Operation>
145 void StrongCheck(const Value& v, const Operation& op, long max_iters = 2000000) {
146  bool succeeded = false;
147  bool failed = false;
149  for ( long count = 0; !succeeded && !failed && count < max_iters; count++ ) {
151 
152  {
153  Value dup = v;
154  {
155 #ifndef EH_NO_EXCEPTIONS
156  try {
157 #endif
159  op( dup );
160  succeeded = true;
162 # ifndef EH_NO_EXCEPTIONS
163  }
164  catch (...) {
166  bool unchanged = (dup == v);
167  EH_ASSERT( unchanged );
168 
169  if ( !unchanged ) {
170 #if 0
171  typedef typename Value::value_type value_type;
172  EH_STD::ostream_iterator<value_type> o(EH_STD::cerr, " ");
173  EH_STD::cerr<<"EH test FAILED:\nStrong guaranee failed !\n";
174  EH_STD::copy(dup.begin(), dup.end(), o);
175  EH_STD::cerr<<"\nOriginal is:\n";
176  EH_STD::copy(v.begin(), v.end(), o);
178 #endif
179  failed = true;
180  }
181  } // Just try again.
182 # endif
183  CheckInvariant(v);
184  }
185  }
186 
187  bool leaked = gTestController.ReportLeaked();
188  EH_ASSERT( !leaked );
189  if ( leaked )
190  failed = true;
191 
192  if ( succeeded )
194  }
195  EH_ASSERT( succeeded || failed ); // Make sure the count hasn't gone over
196 }
197 
198 #endif // INCLUDED_MOTU_LeakCheck
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
#define EH_END_NAMESPACE
Definition: Prefix.h:65
#define EH_BEGIN_NAMESPACE
Definition: Prefix.h:64
static bool ReportLeaked()
Definition: nc_alloc.cpp:290
GLuint GLuint GLsizei count
Definition: gl.h:1545
TestController gTestController
Definition: nc_alloc.cpp:46
void WeakCheck(const Value &v, const Operation &op, long max_iters=2000000)
Definition: LeakCheck.h:65
EH_END_NAMESPACE void CheckInvariant(const C &)
Definition: LeakCheck.h:52
static void BeginLeakDetection()
Definition: nc_alloc.h:147
basic_ostream< _CharT, _Traits > &_STLP_CALL endl(basic_ostream< _CharT, _Traits > &__os)
Definition: _ostream.h:357
static void SetFailureCountdown(long n)
Definition: nc_alloc.h:138
_STLP_DECLSPEC _Stl_aligned_buffer< ostream > cerr
Definition: iostream.cpp:102
void ConstCheck(const Value &v, const Operation &op, long max_iters=2000000)
Definition: LeakCheck.h:103
#define EH_ASSERT
Definition: Prefix.h:37
GLdouble s
Definition: gl.h:2039
static void SetCurrentTestCategory(const char *str)
Definition: nc_alloc.h:162
const GLdouble * v
Definition: gl.h:2040
Definition: ttei6.cpp:27
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
Definition: _pair.h:47
EH_BEGIN_NAMESPACE ostream & operator<<(ostream &s, const pair< T1, T2 > &p)
Definition: LeakCheck.h:38
_Check_return_ _CRTIMP int __cdecl dup(_In_ int _FileHandle)
_In_ FLT_SET_CONTEXT_OPERATION Operation
Definition: fltkernel.h:1468
static void ReportSuccess(int)
Definition: nc_alloc.cpp:328
UINT op
Definition: effect.c:223
static void CancelFailureCountdown()
Definition: nc_alloc.h:143
GLfloat GLfloat p
Definition: glext.h:8902
void StrongCheck(const Value &v, const Operation &op, long max_iters=2000000)
Definition: LeakCheck.h:145