cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
debug.h
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * cryptlib Debug Header File *
4 * Copyright Peter Gutmann 1992-2007 *
5 * *
6 ****************************************************************************/
7 
8 #ifndef _DEBUG_DEFINED
9 
10 #define _DEBUG_DEFINED
11 
12 /****************************************************************************
13 * *
14 * assert() Handling *
15 * *
16 ****************************************************************************/
17 
18 /* Older WinCE environments don't support assert() because there's no
19  console and no other support for it in the runtime (the documentation
20  claims there's at least an _ASSERT/_ASSERTE available, but this isn't
21  present in many systems such as PocketPC), so we use it if it's available
22  and otherwise kludge it using NKDbgPrintfW().
23 
24  Note that (in theory) the version check isn't reliable since we should be
25  checking for the development environment version rather than the target
26  OS version, however in practice compiler/SDK version == OS version unless
27  you seriously enjoy pain, and in any case it's not really possible to
28  differentiate between eVC++ 3.0 and 4.0 - the SHx, MIPS, and ARM compilers
29  at least report 120{1|2} for 3.0 and 1200 for 3.0, but the x86 compiler
30  reports 1200 for both 3.0 and 4.0 even though it's a different build,
31  0.8168 vs. 0.8807 */
32 
33 #if defined( __WINCE__ ) && _WIN32_WCE < 400
34  #if 0 /* Too nonportable, see comment above */
35  #ifndef _ASSERTE
36  #ifdef NDEBUG
37  #define _ASSERTE( x )
38  #else
39  #define _ASSERTE( expr ) \
40  ( void )( ( expr ) || ( NKDbgPrintfW( #expr ) ) )
41  #endif /* Debug vs. non-debug builds */
42  #endif /* _ASSERTE available */
43  #define assert( expr ) _ASSERTE( expr )
44  #else
45  #ifdef NDEBUG
46  #define assert( x )
47  #else
48  #define assert( x ) \
49  DEBUGMSG( !( x ), ( TEXT( "Assert failed in %s line %d: %s" ), TEXT( __FILE__ ), __LINE__, TEXT( #x ) ) )
50  #endif /* Debug vs. non-debug builds */
51  #endif /* 0 */
52 #else
53  #include <assert.h>
54 #endif /* Systems without assert() */
55 
56 /* Assertions can't be used to detect post-prepeocessing compile-time
57  problems, typically using expressions involving sizeof(). Newer versions
58  of the C standard added static_assert() to deal with this, since only
59  recent compilers support this we have to enable it as required, in some
60  cases using preprocessor kludges.
61 
62  In addition to the standard static_assert() we also define an alternative,
63  static_assert_opt(), for cases where the compiler isn't tough enough to
64  handle the standard static_assert(). This occurs with expressions like
65  "foo"[ 1 ] == 'o' */
66 
67 #define ASSERT_CONCAT_( a, b ) a##b
68 #define ASSERT_CONCAT( a, b ) ASSERT_CONCAT_( a, b )
69 #ifndef __COUNTER__
70  /* We need a unique name for each static assertion, ideally we'd like to
71  use a unique value for this but if it's not available (it's supported
72  in the major platforms VC++ and gcc) then we use the next-best thing */
73  #define __COUNTER__ __LINE__
74 #endif /* __COUNTER__ */
75 #if defined( _MSC_VER )
76  #if VC_GE_2010( _MSC_VER )
77  /* Built into VC++ 2010 and up */
78  #elif VC_GE_2008( _MSC_VER ) /* Partial support in VC++ 2008 */
79  #define static_assert( expr, string ) _STATIC_ASSERT( expr )
80  #else
81  #define static_assert( expr, string ) \
82  { enum { ASSERT_CONCAT( static_assert_, __COUNTER__ ) = 1 / ( !!( expr ) ) }; }
83  #endif /* VC++ versions */
84  #define static_assert_opt( expr, string ) \
85  assert( expr )
86 #else
87  #define static_assert( expr, string ) \
88  { enum { ASSERT_CONCAT( static_assert_, __COUNTER__ ) = 1 / ( !!( expr ) ) }; }
89  #define static_assert_opt( expr, string ) \
90  assert( expr )
91 #endif /* VC++ vs. other compilers */
92 
93 /* Force an assertion failure via assert( DEBUG_WARN ) */
94 
95 #define DEBUG_WARN 0
96 
97 /****************************************************************************
98 * *
99 * Debugging Diganostic Functions *
100 * *
101 ****************************************************************************/
102 
103 /* As a safeguard the following debugging functions are only enabled by
104  default in the Win32 debug version to prevent them from being
105  accidentally enabled in any release version, or for the Suite B test
106  build, which is expected to dump diagnostic information to the debug
107  output. Note that the required support functions are present for non-
108  Windows OSes, they're just disabled at this level for safety purposes
109  because the cl32.dll with debug options safely disabled is included with
110  the release while there's no control over which version gets built for
111  other releases. If you know what you're doing then you can enable the
112  debug-dump options by defining the following when you build the code */
113 
114 #if !defined( NDEBUG ) && \
115  ( defined( __WIN32__ ) || defined( CONFIG_SUITEB_TESTS ) )
116  #define DEBUG_DIAGNOSTIC_ENABLE
117 #endif /* 0 */
118 
119 /* Debugging printf() that sends its output to the debug output. Under
120  Windows and eCos this is the debugger, under Unix it's the next-best
121  thing, stderr, on anything else we have to use stdout. In addition
122  since we sometimes need to output pre-formatted strings (which may
123  contain '%' signs interpreted by printf()) we also provide an alternative
124  that just outputs a fixed text string */
125 
126 #if defined( NDEBUG ) && !defined( DEBUG_DIAGNOSTIC_ENABLE )
127  #define DEBUG_PRINT( x )
128  #define DEBUG_OUT( string )
129 #elif defined( __WIN32__ )
130  int debugPrintf( const char *format, ... );
131 
132  #define DEBUG_PRINT( x ) debugPrintf x
133  #define DEBUG_OUT( string ) OutputDebugString( string )
134 #elif defined( __WINCE__ )
135  int debugPrintf( const char *format, ... );
136 
137  #define DEBUG_PRINT( x ) debugPrintf x
138  #define DEBUG_OUT( string ) NKDbgPrintfW( L"%s", string )
139 #elif defined( __ECOS__ )
140  #define DEBUG_PRINT( x ) diag_printf x
141  #define DEBUG_OUT( string ) diag_printf( "%s", string )
142 #elif defined( __UNIX__ )
143  int debugPrintf( const char *format, ... );
144 
145  #define DEBUG_PRINT( x ) debugPrintf x
146  #define DEBUG_OUT( string ) debugPrintf( "%s", string )
147 #else
148  #include <stdio.h> /* Needed for printf() */
149  #define DEBUG_PRINT( x ) printf x
150  #define DEBUG_OUT( string ) printf( "%s", string )
151 #endif /* OS-specific diagnostic functions */
152 
153 /* Output an I-am-here to the debugging outout (see above), useful when
154  tracing errors in code without debug symbols available */
155 
156 #if defined( __GNUC__ ) || ( defined( _MSC_VER ) && VC_GE_2005( _MSC_VER ) )
157  /* Older versions of gcc don't support the current syntax */
158  #if defined( __GNUC__ ) && ( __STDC_VERSION__ < 199901L )
159  #if __GNUC__ >= 2
160  #define __FUNCTION__ __func__
161  #else
162  #define __FUNCTION__ "<unknown>"
163  #endif /* gcc 2.x or newer */
164  #endif /* gcc without __FUNCTION__ support */
165 
166  #define DEBUG_ENTER() DEBUG_PRINT(( "Enter %s:%s:%d.\n", __FILE__, __FUNCTION__, __LINE__ ))
167  #define DEBUG_IN() DEBUG_PRINT(( "In %s:%s:%d.\n", __FILE__, __FUNCTION__, __LINE__ ))
168  #define DEBUG_EXIT() DEBUG_PRINT(( "Exit %s:%s:%d, status %d.\n", __FILE__, __FUNCTION__, __LINE__, status ))
169  #define DEBUG_EXIT_NONE() \
170  DEBUG_PRINT(( "Exit %s:%s:%d.\n", __FILE__, __FUNCTION__, __LINE__ ))
171 
172  #define DEBUG_DIAG( x ) \
173  DEBUG_PRINT(( "%s:%s:%d: ", __FILE__, __FUNCTION__, __LINE__ )); \
174  DEBUG_PRINT( x ); \
175  DEBUG_PRINT(( ".\n" ))
176 #else
177  #define DEBUG_ENTER() DEBUG_PRINT(( "Enter %s:%d.\n", __FILE__, __LINE__ ))
178  #define DEBUG_IN() DEBUG_PRINT(( "In %s:%d.\n", __FILE__, __LINE__ ))
179  #define DEBUG_EXIT() DEBUG_PRINT(( "Exit %s:%d, status %d.\n", __FILE__, __LINE__, status ))
180  #define DEBUG_EXIT_NONE() \
181  DEBUG_PRINT(( "Exit %s:%d.\n", __FILE__, __LINE__ ))
182 
183  #define DEBUG_DIAG( x ) \
184  DEBUG_PRINT(( "%s:%d: ", __FILE__, __LINE__ )); \
185  DEBUG_PRINT( x ); \
186  DEBUG_PRINT(( ".\n" ))
187 #endif /* Compiler-specific diagnotics */
188 
189 /* Dump a PDU to disk or screen. The debug functions do the following:
190 
191  DEBUG_DUMP_FILE: Writes a block of memory to a file in $TMP, suffix
192  ".der".
193 
194  DEBUG_DUMP_CERT: Writes a certificate object to a file, details as for
195  DEBUG_DUMP_FILE().
196 
197  DEBUG_DUMP_HEX: Creates a hex + text dump of a block of memory along
198  with a length and checksum of the entire buffer, prepended with a
199  supplied text string.
200 
201  DEBUG_DUMP_DATA: Creates a hex + text dump of a block of memory, to be
202  used in conjunction with DEBUG_PRINT() for free-format text.
203 
204  DEBUG_DUMP_STREAM: As DEBUG_DUMP_DATA() but taking its input from a
205  stream.
206 
207  DEBUG_GET_STREAMBYTE: Support function for DEBUG_DUMP_STREAM() that
208  pulls data bytes, typically containing type information, out of a
209  stream for display */
210 
211 #if defined( NDEBUG ) && !defined( DEBUG_DIAGNOSTIC_ENABLE )
212  #define DEBUG_DUMP_FILE( name, data, length )
213  #define DEBUG_DUMP_CERT( name, data, length )
214  #define DEBUG_DUMP_HEX( dumpPrefix, dumpBuf, dumpLen )
215  #define DEBUG_DUMP_DATA( dumpBuf, dumpLen )
216  #define DEBUG_DUMP_STREAM( stream, position, length )
217  #define DEBUG_GET_STREAMBYTE( stream, position ) 0
218 #else
219  #define DEBUG_DUMP_FILE debugDumpFile
220  #define DEBUG_DUMP_CERT debugDumpFileCert
221  #define DEBUG_DUMP_HEX debugDumpHex
222  #define DEBUG_DUMP_DATA debugDumpData
223  #define DEBUG_DUMP_STREAM debugDumpStream
224  #define DEBUG_GET_STREAMBYTE debugGetStreamByte
225 
226  STDC_NONNULL_ARG( ( 1, 2 ) ) \
227  void debugDumpFile( IN_STRING const char *fileName,
228  IN_BUFFER( dataLength ) const void *data,
230  STDC_NONNULL_ARG( ( 1 ) ) \
231  void debugDumpFileCert( IN_STRING const char *fileName,
233  STDC_NONNULL_ARG( ( 1, 2 ) ) \
234  void debugDumpHex( IN_STRING const char *prefixString,
235  IN_BUFFER( dataLength ) const void *data,
236  IN_LENGTH_SHORT const int dataLength );
237  STDC_NONNULL_ARG( ( 1 ) ) \
238  void debugDumpData( IN_BUFFER( dataLength ) const void *data,
239  IN_LENGTH_SHORT const int dataLength );
240  STDC_NONNULL_ARG( ( 1 ) ) \
241  void debugDumpStream( INOUT /*STREAM*/ void *streamPtr,
242  IN_LENGTH const int position,
243  IN_LENGTH const int length );
244  CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
245  int debugGetStreamByte( INOUT /*STREAM*/ void *streamPtr,
246  IN_LENGTH const int position );
247 #endif /* Win32 debug */
248 
249 /* Dump a trace of a double-linked list. This has to be done as a macro
250  because it requires in-place substitution of code */
251 
252 #if defined( NDEBUG ) && !defined( DEBUG_DIAGNOSTIC_ENABLE )
253  #define DEBUG_DUMP_LIST( label, listHead, listTail, listType )
254 #else
255  #define DEBUG_DUMP_LIST( label, listHead, listTail, listType ) \
256  { \
257  listType *listPtr; \
258  \
259  DEBUG_PRINT(( "%s: Walking list beginning at %lX.\n", \
260  label, ( listHead ) )); \
261  for( listPtr = ( listHead ); \
262  listPtr != NULL; listPtr = listPtr->next ) \
263  { \
264  DEBUG_PRINT(( " Ptr = %lX, prev = %lX, next = %lX.\n", \
265  listPtr, listPtr->prev, listPtr->next )); \
266  } \
267  if( ( listHead ) != NULL ) \
268  DEBUG_PRINT(( " List tail = %lX.\n", ( listTail ) )); \
269  DEBUG_PRINT(( "Finished walking list beginning at %lX.\n", ( listHead ) )); \
270  }
271 #endif /* NDEBUG */
272 
273 /****************************************************************************
274 * *
275 * Memory Debugging Functions *
276 * *
277 ****************************************************************************/
278 
279 /* In order to debug memory usage, we can define CONFIG_DEBUG_MALLOC to dump
280  memory usage diagnostics to stdout (this would usually be done in the
281  makefile). Without this, the debug malloc just becomes a standard malloc.
282  Note that crypt/osconfig.h contains its own debug-malloc() handling for
283  the OpenSSL-derived code enabled via USE_BN_DEBUG_MALLOC in osconfig.h,
284  and zlib also has its own allocation code (which isn't instrumented for
285  diagnostic purposes).
286 
287  In addition in order to control on-demand allocation of buffers for
288  larger-than-normal data items, we can define CONFIG_NO_DYNALLOC to
289  disable this allocation. This is useful in memory-constrained
290  environments where we can't afford to grab chunks of memory at random */
291 
292 #ifdef CONFIG_DEBUG_MALLOC
293  #undef clAlloc
294  #undef clFree
295  #define clAlloc( string, size ) \
296  clAllocFn( __FILE__, ( string ), __LINE__, ( size ) )
297  #define clFree( string, memblock ) \
298  clFreeFn( __FILE__, ( string ), __LINE__, ( memblock ) )
299  void *clAllocFn( const char *fileName, const char *fnName,
300  const int lineNo, size_t size );
301  void clFreeFn( const char *fileName, const char *fnName,
302  const int lineNo, void *memblock );
303 #else
304  #define clAlloc( string, size ) malloc( size )
305  #define clFree( string, memblock ) free( memblock )
306 #endif /* !CONFIG_DEBUG_MALLOC */
307 #ifdef CONFIG_NO_DYNALLOC
308  #define clDynAlloc( string, size ) NULL
309 #else
310  #define clDynAlloc( string, size ) clAlloc( string, size )
311 #endif /* CONFIG_NO_DYNALLOC */
312 
313 /* To provide fault-injection testing capabilities we can have memory
314  allocations fail after a given count, thus exercising a large number of
315  failure code paths that are normally never taken. The following
316  configuration define enables this fault-malloc(), with the first call
317  setting the allocation call at which failure occurs */
318 
319 #ifdef CONFIG_FAULT_MALLOC
320  #undef clAlloc
321  #undef clFree
322  #define clAlloc( string, size ) \
323  clFaultAllocFn( __FILE__, ( string ), __LINE__, ( size ) )
324  #define clFree( string, memblock ) free( memblock )
325  void *clFaultAllocFn( const char *fileName, const char *fnName,
326  const int lineNo, size_t size );
327  void clFaultSet( const int number );
328 #endif /* CONFIG_FAULT_MALLOC */
329 
330 #endif /* _DEBUG_DEFINED */