ruby-xslt 0.9.2
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +23 -0
- data/COPYING +340 -0
- data/ChangeLog +64 -0
- data/README +137 -0
- data/debug/memwatch.c +2664 -0
- data/debug/memwatch.h +707 -0
- data/examples/commentary.dtd +34 -0
- data/examples/functions.xsl +51 -0
- data/examples/fuzface.rb +13 -0
- data/examples/fuzface.xml +154 -0
- data/examples/fuzface.xsl +4 -0
- data/examples/fuzface_REXML.rb +11 -0
- data/examples/fuzface_XML-Simple.rb +12 -0
- data/examples/fuzface_data.rb +13 -0
- data/examples/fuzface_error.rb +86 -0
- data/examples/fuzface_to_s.rb +9 -0
- data/examples/info.rb +19 -0
- data/examples/ramblings.xsl +46 -0
- data/examples/test.xml +5 -0
- data/examples/test.xsl +18 -0
- data/examples/test_functions.rb +18 -0
- data/examples/test_parameters.rb +13 -0
- data/extconf.rb +114 -0
- data/extfunc.c +216 -0
- data/extfunc.h +26 -0
- data/parameters.c +59 -0
- data/parameters.h +20 -0
- data/parser.c +228 -0
- data/parser.h +30 -0
- data/rb_utils.c +30 -0
- data/rb_utils.h +34 -0
- data/ruby-xslt.gemspec +19 -0
- data/tests/t.xml +2 -0
- data/tests/t.xsl +6 -0
- data/tests/test.rb +125 -0
- data/xslt.c +619 -0
- data/xslt.h +98 -0
- metadata +98 -0
data/debug/memwatch.h
ADDED
@@ -0,0 +1,707 @@
|
|
1
|
+
/*
|
2
|
+
** MEMWATCH.H
|
3
|
+
** Nonintrusive ANSI C memory leak / overwrite detection
|
4
|
+
** Copyright (C) 1992-2002 Johan Lindh
|
5
|
+
** All rights reserved.
|
6
|
+
** Version 2.71
|
7
|
+
**
|
8
|
+
************************************************************************
|
9
|
+
**
|
10
|
+
** PURPOSE:
|
11
|
+
**
|
12
|
+
** MEMWATCH has been written to allow guys and gals that like to
|
13
|
+
** program in C a public-domain memory error control product.
|
14
|
+
** I hope you'll find it's as advanced as most commercial packages.
|
15
|
+
** The idea is that you use it during the development phase and
|
16
|
+
** then remove the MEMWATCH define to produce your final product.
|
17
|
+
** MEMWATCH is distributed in source code form in order to allow
|
18
|
+
** you to compile it for your platform with your own compiler.
|
19
|
+
** It's aim is to be 100% ANSI C, but some compilers are more stingy
|
20
|
+
** than others. If it doesn't compile without warnings, please mail
|
21
|
+
** me the configuration of operating system and compiler you are using
|
22
|
+
** along with a description of how to modify the source, and the version
|
23
|
+
** number of MEMWATCH that you are using.
|
24
|
+
**
|
25
|
+
************************************************************************
|
26
|
+
|
27
|
+
This file is part of MEMWATCH.
|
28
|
+
|
29
|
+
MEMWATCH is free software; you can redistribute it and/or modify
|
30
|
+
it under the terms of the GNU General Public License as published by
|
31
|
+
the Free Software Foundation; either version 2 of the License, or
|
32
|
+
(at your option) any later version.
|
33
|
+
|
34
|
+
MEMWATCH is distributed in the hope that it will be useful,
|
35
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
36
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
37
|
+
GNU General Public License for more details.
|
38
|
+
|
39
|
+
You should have received a copy of the GNU General Public License
|
40
|
+
along with MEMWATCH; if not, write to the Free Software
|
41
|
+
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
42
|
+
|
43
|
+
************************************************************************
|
44
|
+
**
|
45
|
+
** REVISION HISTORY:
|
46
|
+
**
|
47
|
+
** 920810 JLI [1.00]
|
48
|
+
** 920830 JLI [1.10 double-free detection]
|
49
|
+
** 920912 JLI [1.15 mwPuts, mwGrab/Drop, mwLimit]
|
50
|
+
** 921022 JLI [1.20 ASSERT and VERIFY]
|
51
|
+
** 921105 JLI [1.30 C++ support and TRACE]
|
52
|
+
** 921116 JLI [1.40 mwSetOutFunc]
|
53
|
+
** 930215 JLI [1.50 modified ASSERT/VERIFY]
|
54
|
+
** 930327 JLI [1.51 better auto-init & PC-lint support]
|
55
|
+
** 930506 JLI [1.55 MemWatch class, improved C++ support]
|
56
|
+
** 930507 JLI [1.60 mwTest & CHECK()]
|
57
|
+
** 930809 JLI [1.65 Abort/Retry/Ignore]
|
58
|
+
** 930820 JLI [1.70 data dump when unfreed]
|
59
|
+
** 931016 JLI [1.72 modified C++ new/delete handling]
|
60
|
+
** 931108 JLI [1.77 mwSetAssertAction() & some small changes]
|
61
|
+
** 940110 JLI [1.80 no-mans-land alloc/checking]
|
62
|
+
** 940328 JLI [2.00 version 2.0 rewrite]
|
63
|
+
** Improved NML (no-mans-land) support.
|
64
|
+
** Improved performance (especially for free()ing!).
|
65
|
+
** Support for 'read-only' buffers (checksums)
|
66
|
+
** ^^ NOTE: I never did this... maybe I should?
|
67
|
+
** FBI (free'd block info) tagged before freed blocks
|
68
|
+
** Exporting of the mwCounter variable
|
69
|
+
** mwBreakOut() localizes debugger support
|
70
|
+
** Allocation statistics (global, per-module, per-line)
|
71
|
+
** Self-repair ability with relinking
|
72
|
+
** 950913 JLI [2.10 improved garbage handling]
|
73
|
+
** 951201 JLI [2.11 improved auto-free in emergencies]
|
74
|
+
** 960125 JLI [X.01 implemented auto-checking using mwAutoCheck()]
|
75
|
+
** 960514 JLI [2.12 undefining of existing macros]
|
76
|
+
** 960515 JLI [2.13 possibility to use default new() & delete()]
|
77
|
+
** 960516 JLI [2.20 suppression of file flushing on unfreed msgs]
|
78
|
+
** 960516 JLI [2.21 better support for using MEMWATCH with DLL's]
|
79
|
+
** 960710 JLI [X.02 multiple logs and mwFlushNow()]
|
80
|
+
** 960801 JLI [2.22 merged X.01 version with current]
|
81
|
+
** 960805 JLI [2.30 mwIsXXXXAddr() to avoid unneeded GP's]
|
82
|
+
** 960805 JLI [2.31 merged X.02 version with current]
|
83
|
+
** 961002 JLI [2.32 support for realloc() + fixed STDERR bug]
|
84
|
+
** 961222 JLI [2.40 added mwMark() & mwUnmark()]
|
85
|
+
** 970101 JLI [2.41 added over/underflow checking after failed ASSERT/VERIFY]
|
86
|
+
** 970113 JLI [2.42 added support for PC-Lint 7.00g]
|
87
|
+
** 970207 JLI [2.43 added support for strdup()]
|
88
|
+
** 970209 JLI [2.44 changed default filename to lowercase]
|
89
|
+
** 970405 JLI [2.45 fixed bug related with atexit() and some C++ compilers]
|
90
|
+
** 970723 JLI [2.46 added MW_ARI_NULLREAD flag]
|
91
|
+
** 970813 JLI [2.47 stabilized marker handling]
|
92
|
+
** 980317 JLI [2.48 ripped out C++ support; wasn't working good anyway]
|
93
|
+
** 980318 JLI [2.50 improved self-repair facilities & SIGSEGV support]
|
94
|
+
** 980417 JLI [2.51 more checks for invalid addresses]
|
95
|
+
** 980512 JLI [2.52 moved MW_ARI_NULLREAD to occur before aborting]
|
96
|
+
** 990112 JLI [2.53 added check for empty heap to mwIsOwned]
|
97
|
+
** 990217 JLI [2.55 improved the emergency repairs diagnostics and NML]
|
98
|
+
** 990224 JLI [2.56 changed ordering of members in structures]
|
99
|
+
** 990303 JLI [2.57 first maybe-fixit-for-hpux test]
|
100
|
+
** 990516 JLI [2.58 added 'static' to the definition of mwAutoInit]
|
101
|
+
** 990517 JLI [2.59 fixed some high-sensitivity warnings]
|
102
|
+
** 990610 JLI [2.60 fixed some more high-sensitivity warnings]
|
103
|
+
** 990715 JLI [2.61 changed TRACE/ASSERT/VERIFY macro names]
|
104
|
+
** 991001 JLI [2.62 added CHECK_BUFFER() and mwTestBuffer()]
|
105
|
+
** 991007 JLI [2.63 first shot at a 64-bit compatible version]
|
106
|
+
** 991009 JLI [2.64 undef's strdup() if defined, mwStrdup made const]
|
107
|
+
** 000704 JLI [2.65 added some more detection for 64-bits]
|
108
|
+
** 010502 JLI [2.66 incorporated some user fixes]
|
109
|
+
** [mwRelink() could print out garbage pointer (thanks mac@phobos.ca)]
|
110
|
+
** [added array destructor for C++ (thanks rdasilva@connecttel.com)]
|
111
|
+
** [added mutex support (thanks rdasilva@connecttel.com)]
|
112
|
+
** 010531 JLI [2.67 fix: mwMutexXXX() was declared even if MW_HAVE_MUTEX was not defined]
|
113
|
+
** 010619 JLI [2.68 fix: mwRealloc() could leave the mutex locked]
|
114
|
+
** 020918 JLI [2.69 changed to GPL, added C++ array allocation by Howard Cohen]
|
115
|
+
** 030212 JLI [2.70 mwMalloc() bug for very large allocations (4GB on 32bits)]
|
116
|
+
** 030520 JLI [2.71 added ULONG_LONG_MAX as a 64-bit detector (thanks Sami Salonen)]
|
117
|
+
**
|
118
|
+
** To use, simply include 'MEMWATCH.H' as a header file,
|
119
|
+
** and add MEMWATCH.C to your list of files, and define the macro
|
120
|
+
** 'MEMWATCH'. If this is not defined, MEMWATCH will disable itself.
|
121
|
+
**
|
122
|
+
** To call the standard C malloc / realloc / calloc / free; use mwMalloc_(),
|
123
|
+
** mwCalloc_() and mwFree_(). Note that mwFree_() will correctly
|
124
|
+
** free both malloc()'d memory as well as mwMalloc()'d.
|
125
|
+
**
|
126
|
+
** 980317: C++ support has been disabled.
|
127
|
+
** The code remains, but is not compiled.
|
128
|
+
**
|
129
|
+
** For use with C++, which allows use of inlining in header files
|
130
|
+
** and class specific new/delete, you must also define 'new' as
|
131
|
+
** 'mwNew' and 'delete' as 'mwDelete'. Do this *after* you include
|
132
|
+
** C++ header files from libraries, otherwise you can mess up their
|
133
|
+
** class definitions. If you don't define these, the C++ allocations
|
134
|
+
** will not have source file and line number information. Also note,
|
135
|
+
** most C++ class libraries implement their own C++ memory management,
|
136
|
+
** and don't allow anyone to override them. MFC belongs to this crew.
|
137
|
+
** In these cases, the only thing to do is to use MEMWATCH_NOCPP.
|
138
|
+
**
|
139
|
+
** You can capture output from MEMWATCH using mwSetOutFunc().
|
140
|
+
** Just give it the adress of a "void myOutFunc(int c)" function,
|
141
|
+
** and all characters to be output will be redirected there.
|
142
|
+
**
|
143
|
+
** A failing ASSERT() or VERIFY() will normally always abort your
|
144
|
+
** program. This can be changed using mwSetAriFunc(). Give it a
|
145
|
+
** pointer to a "int myAriFunc(const char *)" function. Your function
|
146
|
+
** must ask the user whether to Abort, Retry or Ignore the trap.
|
147
|
+
** Return 2 to Abort, 1 to Retry or 0 to Ignore. Beware retry; it
|
148
|
+
** causes the expression to be evaluated again! MEMWATCH has a
|
149
|
+
** default ARI handler. It's disabled by default, but you can enable
|
150
|
+
** it by calling 'mwDefaultAri()'. Note that this will STILL abort
|
151
|
+
** your program unless you define MEMWATCH_STDIO to allow MEMWATCH
|
152
|
+
** to use the standard C I/O streams. Also, setting the ARI function
|
153
|
+
** will cause MEMWATCH *NOT* to write the ARI error to stderr. The
|
154
|
+
** error string is passed to the ARI function instead, as the
|
155
|
+
** 'const char *' parameter.
|
156
|
+
**
|
157
|
+
** You can disable MEMWATCH's ASSERT/VERIFY and/or TRACE implementations.
|
158
|
+
** This can be useful if you're using a debug terminal or smart debugger.
|
159
|
+
** Disable them by defining MW_NOASSERT, MW_NOVERIFY or MW_NOTRACE.
|
160
|
+
**
|
161
|
+
** MEMWATCH fills all allocated memory with the byte 0xFE, so if
|
162
|
+
** you're looking at erroneous data which are all 0xFE:s, the
|
163
|
+
** data probably was not initialized by you. The exception is
|
164
|
+
** calloc(), which will fill with zero's. All freed buffers are
|
165
|
+
** zapped with 0xFD. If this is what you look at, you're using
|
166
|
+
** data that has been freed. If this is the case, be aware that
|
167
|
+
** MEMWATCH places a 'free'd block info' structure immediately
|
168
|
+
** before the freed data. This block contains info about where
|
169
|
+
** the block was freed. The information is in readable text,
|
170
|
+
** in the format "FBI<counter>filename(line)", for example:
|
171
|
+
** "FBI<267>test.c(12)". Using FBI's slows down free(), so it's
|
172
|
+
** disabled by default. Use mwFreeBufferInfo(1) to enable it.
|
173
|
+
**
|
174
|
+
** To aid in tracking down wild pointer writes, MEMWATCH can perform
|
175
|
+
** no-mans-land allocations. No-mans-land will contain the byte 0xFC.
|
176
|
+
** MEMWATCH will, when this is enabled, convert recently free'd memory
|
177
|
+
** into NML allocations.
|
178
|
+
**
|
179
|
+
** MEMWATCH protects it's own data buffers with checksums. If you
|
180
|
+
** get an internal error, it means you're overwriting wildly,
|
181
|
+
** or using an uninitialized pointer.
|
182
|
+
**
|
183
|
+
************************************************************************
|
184
|
+
**
|
185
|
+
** Note when compiling with Microsoft C:
|
186
|
+
** - MSC ignores fflush() by default. This is overridden, so that
|
187
|
+
** the disk log will always be current.
|
188
|
+
**
|
189
|
+
** This utility has been tested with:
|
190
|
+
** PC-lint 7.0k, passed as 100% ANSI C compatible
|
191
|
+
** Microsoft Visual C++ on Win16 and Win32
|
192
|
+
** Microsoft C on DOS
|
193
|
+
** SAS C on an Amiga 500
|
194
|
+
** Gnu C on a PC running Red Hat Linux
|
195
|
+
** ...and using an (to me) unknown compiler on an Atari machine.
|
196
|
+
**
|
197
|
+
************************************************************************
|
198
|
+
**
|
199
|
+
** Format of error messages in MEMWATCH.LOG:
|
200
|
+
** message: <sequence-number> filename(linenumber), information
|
201
|
+
**
|
202
|
+
** Errors caught by MemWatch, when they are detected, and any
|
203
|
+
** actions taken besides writing to the log file MEMWATCH.LOG:
|
204
|
+
**
|
205
|
+
** Double-freeing:
|
206
|
+
** A pointer that was recently freed and has not since been
|
207
|
+
** reused was freed again. The place where the previous free()
|
208
|
+
** was executed is displayed.
|
209
|
+
** Detect: delete or free() using the offending pointer.
|
210
|
+
** Action: The delete or free() is cancelled, execution continues.
|
211
|
+
** Underflow:
|
212
|
+
** You have written just ahead of the allocated memory.
|
213
|
+
** The size and place of the allocation is displayed.
|
214
|
+
** Detect: delete or free() of the damaged buffer.
|
215
|
+
** Action: The buffer is freed, but there may be secondary damage.
|
216
|
+
** Overflow:
|
217
|
+
** Like underflow, but you've written after the end of the buffer.
|
218
|
+
** Detect: see Underflow.
|
219
|
+
** Action: see Underflow.
|
220
|
+
** WILD free:
|
221
|
+
** An unrecognized pointer was passed to delete or free().
|
222
|
+
** The pointer may have been returned from a library function;
|
223
|
+
** in that case, use mwFree_() to force free() of it.
|
224
|
+
** Also, this may be a double-free, but the previous free was
|
225
|
+
** too long ago, causing MEMWATCH to 'forget' it.
|
226
|
+
** Detect: delete or free() of the offending pointer.
|
227
|
+
** Action: The delete or free() is cancelled, execution continues.
|
228
|
+
** NULL free:
|
229
|
+
** It's unclear to me whether or not freeing of NULL pointers
|
230
|
+
** is legal in ANSI C, therefore a warning is written to the log file,
|
231
|
+
** but the error counter remains the same. This is legal using C++,
|
232
|
+
** so the warning does not appear with delete.
|
233
|
+
** Detect: When you free(NULL).
|
234
|
+
** Action: The free() is cancelled.
|
235
|
+
** Failed:
|
236
|
+
** A request to allocate memory failed. If the allocation is
|
237
|
+
** small, this may be due to memory depletion, but is more likely
|
238
|
+
** to be memory fragmentation problems. The amount of memory
|
239
|
+
** allocated so far is displayed also.
|
240
|
+
** Detect: When you new, malloc(), realloc() or calloc() memory.
|
241
|
+
** Action: NULL is returned.
|
242
|
+
** Realloc:
|
243
|
+
** A request to re-allocate a memory buffer failed for reasons
|
244
|
+
** other than out-of-memory. The specific reason is shown.
|
245
|
+
** Detect: When you realloc()
|
246
|
+
** Action: realloc() is cancelled, NULL is returned
|
247
|
+
** Limit fail:
|
248
|
+
** A request to allocate memory failed since it would violate
|
249
|
+
** the limit set using mwLimit(). mwLimit() is used to stress-test
|
250
|
+
** your code under simulated low memory conditions.
|
251
|
+
** Detect: At new, malloc(), realloc() or calloc().
|
252
|
+
** Action: NULL is returned.
|
253
|
+
** Assert trap:
|
254
|
+
** An ASSERT() failed. The ASSERT() macro works like C's assert()
|
255
|
+
** macro/function, except that it's interactive. See your C manual.
|
256
|
+
** Detect: On the ASSERT().
|
257
|
+
** Action: Program ends with an advisory message to stderr, OR
|
258
|
+
** Program writes the ASSERT to the log and continues, OR
|
259
|
+
** Program asks Abort/Retry/Ignore? and takes that action.
|
260
|
+
** Verify trap:
|
261
|
+
** A VERIFY() failed. The VERIFY() macro works like ASSERT(),
|
262
|
+
** but if MEMWATCH is not defined, it still evaluates the
|
263
|
+
** expression, but it does not act upon the result.
|
264
|
+
** Detect: On the VERIFY().
|
265
|
+
** Action: Program ends with an advisory message to stderr, OR
|
266
|
+
** Program writes the VERIFY to the log and continues, OR
|
267
|
+
** Program asks Abort/Retry/Ignore? and takes that action.
|
268
|
+
** Wild pointer:
|
269
|
+
** A no-mans-land buffer has been written into. MEMWATCH can
|
270
|
+
** allocate and distribute chunks of memory solely for the
|
271
|
+
** purpose of trying to catch random writes into memory.
|
272
|
+
** Detect: Always on CHECK(), but can be detected in several places.
|
273
|
+
** Action: The error is logged, and if an ARI handler is installed,
|
274
|
+
** it is executed, otherwise, execution continues.
|
275
|
+
** Unfreed:
|
276
|
+
** A memory buffer you allocated has not been freed.
|
277
|
+
** You are informed where it was allocated, and whether any
|
278
|
+
** over or underflow has occured. MemWatch also displays up to
|
279
|
+
** 16 bytes of the data, as much as it can, in hex and text.
|
280
|
+
** Detect: When MemWatch terminates.
|
281
|
+
** Action: The buffer is freed.
|
282
|
+
** Check:
|
283
|
+
** An error was detected during a CHECK() operation.
|
284
|
+
** The associated pointer is displayed along with
|
285
|
+
** the file and line where the CHECK() was executed.
|
286
|
+
** Followed immediately by a normal error message.
|
287
|
+
** Detect: When you CHECK()
|
288
|
+
** Action: Depends on the error
|
289
|
+
** Relink:
|
290
|
+
** After a MEMWATCH internal control block has been trashed,
|
291
|
+
** MEMWATCH tries to repair the damage. If successful, program
|
292
|
+
** execution will continue instead of aborting. Some information
|
293
|
+
** about the block may be gone permanently, though.
|
294
|
+
** Detect: N/A
|
295
|
+
** Action: Relink successful: program continues.
|
296
|
+
** Relink fails: program aborts.
|
297
|
+
** Internal:
|
298
|
+
** An internal error is flagged by MEMWATCH when it's control
|
299
|
+
** structures have been damaged. You are likely using an uninitialized
|
300
|
+
** pointer somewhere in your program, or are zapping memory all over.
|
301
|
+
** The message may give you additional diagnostic information.
|
302
|
+
** If possible, MEMWATCH will recover and continue execution.
|
303
|
+
** Detect: Various actions.
|
304
|
+
** Action: Whatever is needed
|
305
|
+
** Mark:
|
306
|
+
** The program terminated without umarking all marked pointers. Marking
|
307
|
+
** can be used to track resources other than memory. mwMark(pointer,text,...)
|
308
|
+
** when the resource is allocated, and mwUnmark(pointer) when it's freed.
|
309
|
+
** The 'text' is displayed for still marked pointers when the program
|
310
|
+
** ends.
|
311
|
+
** Detect: When MemWatch terminates.
|
312
|
+
** Action: The error is logged.
|
313
|
+
**
|
314
|
+
**
|
315
|
+
************************************************************************
|
316
|
+
**
|
317
|
+
** The author may be reached by e-mail at the address below. If you
|
318
|
+
** mail me about source code changes in MEMWATCH, remember to include
|
319
|
+
** MW's version number.
|
320
|
+
**
|
321
|
+
** Johan Lindh
|
322
|
+
** johan@linkdata.se
|
323
|
+
**
|
324
|
+
** The latest version of MEMWATCH may be downloaded from
|
325
|
+
** http://www.linkdata.se/
|
326
|
+
*/
|
327
|
+
|
328
|
+
#ifndef __MEMWATCH_H
|
329
|
+
#define __MEMWATCH_H
|
330
|
+
|
331
|
+
/* Make sure that malloc(), realloc(), calloc() and free() are declared. */
|
332
|
+
/*lint -save -e537 */
|
333
|
+
#include <stdlib.h>
|
334
|
+
/*lint -restore */
|
335
|
+
|
336
|
+
#ifdef __cplusplus
|
337
|
+
extern "C" {
|
338
|
+
#endif
|
339
|
+
|
340
|
+
|
341
|
+
/*
|
342
|
+
** Constants used
|
343
|
+
** All MEMWATCH constants start with the prefix MW_, followed by
|
344
|
+
** a short mnemonic which indicates where the constant is used,
|
345
|
+
** followed by a descriptive text about it.
|
346
|
+
*/
|
347
|
+
|
348
|
+
#define MW_ARI_NULLREAD 0x10 /* Null read (to start debugger) */
|
349
|
+
#define MW_ARI_ABORT 0x04 /* ARI handler says: abort program! */
|
350
|
+
#define MW_ARI_RETRY 0x02 /* ARI handler says: retry action! */
|
351
|
+
#define MW_ARI_IGNORE 0x01 /* ARI handler says: ignore error! */
|
352
|
+
|
353
|
+
#define MW_VAL_NEW 0xFE /* value in newly allocated memory */
|
354
|
+
#define MW_VAL_DEL 0xFD /* value in newly deleted memory */
|
355
|
+
#define MW_VAL_NML 0xFC /* value in no-mans-land */
|
356
|
+
#define MW_VAL_GRB 0xFB /* value in grabbed memory */
|
357
|
+
|
358
|
+
#define MW_TEST_ALL 0xFFFF /* perform all tests */
|
359
|
+
#define MW_TEST_CHAIN 0x0001 /* walk the heap chain */
|
360
|
+
#define MW_TEST_ALLOC 0x0002 /* test allocations & NML guards */
|
361
|
+
#define MW_TEST_NML 0x0004 /* test all-NML areas for modifications */
|
362
|
+
|
363
|
+
#define MW_NML_NONE 0 /* no NML */
|
364
|
+
#define MW_NML_FREE 1 /* turn FREE'd memory into NML */
|
365
|
+
#define MW_NML_ALL 2 /* all unused memory is NML */
|
366
|
+
#define MW_NML_DEFAULT 0 /* the default NML setting */
|
367
|
+
|
368
|
+
#define MW_STAT_GLOBAL 0 /* only global statistics collected */
|
369
|
+
#define MW_STAT_MODULE 1 /* collect statistics on a module basis */
|
370
|
+
#define MW_STAT_LINE 2 /* collect statistics on a line basis */
|
371
|
+
#define MW_STAT_DEFAULT 0 /* the default statistics setting */
|
372
|
+
|
373
|
+
/*
|
374
|
+
** MemWatch internal constants
|
375
|
+
** You may change these and recompile MemWatch to change the limits
|
376
|
+
** of some parameters. Respect the recommended minimums!
|
377
|
+
*/
|
378
|
+
#define MW_TRACE_BUFFER 2048 /* (min 160) size of TRACE()'s output buffer */
|
379
|
+
#define MW_FREE_LIST 64 /* (min 4) number of free()'s to track */
|
380
|
+
|
381
|
+
/*
|
382
|
+
** Exported variables
|
383
|
+
** In case you have to remove the 'const' keyword because your compiler
|
384
|
+
** doesn't support it, be aware that changing the values may cause
|
385
|
+
** unpredictable behaviour.
|
386
|
+
** - mwCounter contains the current action count. You can use this to
|
387
|
+
** place breakpoints using a debugger, if you want.
|
388
|
+
*/
|
389
|
+
#ifndef __MEMWATCH_C
|
390
|
+
extern const unsigned long mwCounter;
|
391
|
+
#endif
|
392
|
+
|
393
|
+
/*
|
394
|
+
** System functions
|
395
|
+
** Normally, it is not nessecary to call any of these. MEMWATCH will
|
396
|
+
** automatically initialize itself on the first MEMWATCH function call,
|
397
|
+
** and set up a call to mwAbort() using atexit(). Some C++ implementations
|
398
|
+
** run the atexit() chain before the program has terminated, so you
|
399
|
+
** may have to use mwInit() or the MemWatch C++ class to get good
|
400
|
+
** behaviour.
|
401
|
+
** - mwInit() can be called to disable the atexit() usage. If mwInit()
|
402
|
+
** is called directly, you must call mwTerm() to end MemWatch, or
|
403
|
+
** mwAbort().
|
404
|
+
** - mwTerm() is usually not nessecary to call; but if called, it will
|
405
|
+
** call mwAbort() if it finds that it is cancelling the 'topmost'
|
406
|
+
** mwInit() call.
|
407
|
+
** - mwAbort() cleans up after MEMWATCH, reports unfreed buffers, etc.
|
408
|
+
*/
|
409
|
+
void mwInit( void );
|
410
|
+
void mwTerm( void );
|
411
|
+
void mwAbort( void );
|
412
|
+
|
413
|
+
/*
|
414
|
+
** Setup functions
|
415
|
+
** These functions control the operation of MEMWATCH's protective features.
|
416
|
+
** - mwFlushNow() causes MEMWATCH to flush it's buffers.
|
417
|
+
** - mwDoFlush() controls whether MEMWATCH flushes the disk buffers after
|
418
|
+
** writes. The default is smart flushing: MEMWATCH will not flush buffers
|
419
|
+
** explicitly until memory errors are detected. Then, all writes are
|
420
|
+
** flushed until program end or mwDoFlush(0) is called.
|
421
|
+
** - mwLimit() sets the allocation limit, an arbitrary limit on how much
|
422
|
+
** memory your program may allocate in bytes. Used to stress-test app.
|
423
|
+
** Also, in virtual-memory or multitasking environs, puts a limit on
|
424
|
+
** how much MW_NML_ALL can eat up.
|
425
|
+
** - mwGrab() grabs up X kilobytes of memory. Allocates actual memory,
|
426
|
+
** can be used to stress test app & OS both.
|
427
|
+
** - mwDrop() drops X kilobytes of grabbed memory.
|
428
|
+
** - mwNoMansLand() sets the behaviour of the NML logic. See the
|
429
|
+
** MW_NML_xxx for more information. The default is MW_NML_DEFAULT.
|
430
|
+
** - mwStatistics() sets the behaviour of the statistics collector. See
|
431
|
+
** the MW_STAT_xxx defines for more information. Default MW_STAT_DEFAULT.
|
432
|
+
** - mwFreeBufferInfo() enables or disables the tagging of free'd buffers
|
433
|
+
** with freeing information. This information is written in text form,
|
434
|
+
** using sprintf(), so it's pretty slow. Disabled by default.
|
435
|
+
** - mwAutoCheck() performs a CHECK() operation whenever a MemWatch function
|
436
|
+
** is used. Slows down performance, of course.
|
437
|
+
** - mwCalcCheck() calculates checksums for all data buffers. Slow!
|
438
|
+
** - mwDumpCheck() logs buffers where stored & calc'd checksums differ. Slow!!
|
439
|
+
** - mwMark() sets a generic marker. Returns the pointer given.
|
440
|
+
** - mwUnmark() removes a generic marker. If, at the end of execution, some
|
441
|
+
** markers are still in existence, these will be reported as leakage.
|
442
|
+
** returns the pointer given.
|
443
|
+
*/
|
444
|
+
void mwFlushNow( void );
|
445
|
+
void mwDoFlush( int onoff );
|
446
|
+
void mwLimit( long bytes );
|
447
|
+
unsigned mwGrab( unsigned kilobytes );
|
448
|
+
unsigned mwDrop( unsigned kilobytes );
|
449
|
+
void mwNoMansLand( int mw_nml_level );
|
450
|
+
void mwStatistics( int level );
|
451
|
+
void mwFreeBufferInfo( int onoff );
|
452
|
+
void mwAutoCheck( int onoff );
|
453
|
+
void mwCalcCheck( void );
|
454
|
+
void mwDumpCheck( void );
|
455
|
+
void * mwMark( void *p, const char *description, const char *file, unsigned line );
|
456
|
+
void * mwUnmark( void *p, const char *file, unsigned line );
|
457
|
+
|
458
|
+
/*
|
459
|
+
** Testing/verification/tracing
|
460
|
+
** All of these macros except VERIFY() evaluates to a null statement
|
461
|
+
** if MEMWATCH is not defined during compilation.
|
462
|
+
** - mwIsReadAddr() checks a memory area for read privilige.
|
463
|
+
** - mwIsSafeAddr() checks a memory area for both read & write privilige.
|
464
|
+
** This function and mwIsReadAddr() is highly system-specific and
|
465
|
+
** may not be implemented. If this is the case, they will default
|
466
|
+
** to returning nonzero for any non-NULL pointer.
|
467
|
+
** - CHECK() does a complete memory integrity test. Slow!
|
468
|
+
** - CHECK_THIS() checks only selected components.
|
469
|
+
** - CHECK_BUFFER() checks the indicated buffer for errors.
|
470
|
+
** - mwASSERT() or ASSERT() If the expression evaluates to nonzero, execution continues.
|
471
|
+
** Otherwise, the ARI handler is called, if present. If not present,
|
472
|
+
** the default ARI action is taken (set with mwSetAriAction()).
|
473
|
+
** ASSERT() can be disabled by defining MW_NOASSERT.
|
474
|
+
** - mwVERIFY() or VERIFY() works just like ASSERT(), but when compiling without
|
475
|
+
** MEMWATCH the macro evaluates to the expression.
|
476
|
+
** VERIFY() can be disabled by defining MW_NOVERIFY.
|
477
|
+
** - mwTRACE() or TRACE() writes some text and data to the log. Use like printf().
|
478
|
+
** TRACE() can be disabled by defining MW_NOTRACE.
|
479
|
+
*/
|
480
|
+
int mwIsReadAddr( const void *p, unsigned len );
|
481
|
+
int mwIsSafeAddr( void *p, unsigned len );
|
482
|
+
int mwTest( const char *file, int line, int mw_test_flags );
|
483
|
+
int mwTestBuffer( const char *file, int line, void *p );
|
484
|
+
int mwAssert( int, const char*, const char*, int );
|
485
|
+
int mwVerify( int, const char*, const char*, int );
|
486
|
+
|
487
|
+
/*
|
488
|
+
** User I/O functions
|
489
|
+
** - mwTrace() works like printf(), but dumps output either to the
|
490
|
+
** function specified with mwSetOutFunc(), or the log file.
|
491
|
+
** - mwPuts() works like puts(), dumps output like mwTrace().
|
492
|
+
** - mwSetOutFunc() allows you to give the adress of a function
|
493
|
+
** where all user output will go. (exeption: see mwSetAriFunc)
|
494
|
+
** Specifying NULL will direct output to the log file.
|
495
|
+
** - mwSetAriFunc() gives MEMWATCH the adress of a function to call
|
496
|
+
** when an 'Abort, Retry, Ignore' question is called for. The
|
497
|
+
** actual error message is NOT printed when you've set this adress,
|
498
|
+
** but instead it is passed as an argument. If you call with NULL
|
499
|
+
** for an argument, the ARI handler is disabled again. When the
|
500
|
+
** handler is disabled, MEMWATCH will automatically take the
|
501
|
+
** action specified by mwSetAriAction().
|
502
|
+
** - mwSetAriAction() sets the default ARI return value MEMWATCH should
|
503
|
+
** use if no ARI handler is specified. Defaults to MW_ARI_ABORT.
|
504
|
+
** - mwAriHandler() is an ANSI ARI handler you can use if you like. It
|
505
|
+
** dumps output to stderr, and expects input from stdin.
|
506
|
+
** - mwBreakOut() is called in certain cases when MEMWATCH feels it would
|
507
|
+
** be nice to break into a debugger. If you feel like MEMWATCH, place
|
508
|
+
** an execution breakpoint on this function.
|
509
|
+
*/
|
510
|
+
void mwTrace( const char* format_string, ... );
|
511
|
+
void mwPuts( const char* text );
|
512
|
+
void mwSetOutFunc( void (*func)(int) );
|
513
|
+
void mwSetAriFunc( int (*func)(const char*) );
|
514
|
+
void mwSetAriAction( int mw_ari_value );
|
515
|
+
int mwAriHandler( const char* cause );
|
516
|
+
void mwBreakOut( const char* cause );
|
517
|
+
|
518
|
+
/*
|
519
|
+
** Allocation/deallocation functions
|
520
|
+
** These functions are the ones actually to perform allocations
|
521
|
+
** when running MEMWATCH, for both C and C++ calls.
|
522
|
+
** - mwMalloc() debugging allocator
|
523
|
+
** - mwMalloc_() always resolves to a clean call of malloc()
|
524
|
+
** - mwRealloc() debugging re-allocator
|
525
|
+
** - mwRealloc_() always resolves to a clean call of realloc()
|
526
|
+
** - mwCalloc() debugging allocator, fills with zeros
|
527
|
+
** - mwCalloc_() always resolves to a clean call of calloc()
|
528
|
+
** - mwFree() debugging free. Can only free memory which has
|
529
|
+
** been allocated by MEMWATCH.
|
530
|
+
** - mwFree_() resolves to a) normal free() or b) debugging free.
|
531
|
+
** Can free memory allocated by MEMWATCH and malloc() both.
|
532
|
+
** Does not generate any runtime errors.
|
533
|
+
*/
|
534
|
+
void* mwMalloc( size_t, const char*, int );
|
535
|
+
void* mwMalloc_( size_t );
|
536
|
+
void* mwRealloc( void *, size_t, const char*, int );
|
537
|
+
void* mwRealloc_( void *, size_t );
|
538
|
+
void* mwCalloc( size_t, size_t, const char*, int );
|
539
|
+
void* mwCalloc_( size_t, size_t );
|
540
|
+
void mwFree( void*, const char*, int );
|
541
|
+
void mwFree_( void* );
|
542
|
+
char* mwStrdup( const char *, const char*, int );
|
543
|
+
|
544
|
+
/*
|
545
|
+
** Enable/disable precompiler block
|
546
|
+
** This block of defines and if(n)defs make sure that references
|
547
|
+
** to MEMWATCH is completely removed from the code if the MEMWATCH
|
548
|
+
** manifest constant is not defined.
|
549
|
+
*/
|
550
|
+
#ifndef __MEMWATCH_C
|
551
|
+
#ifdef MEMWATCH
|
552
|
+
|
553
|
+
#define mwASSERT(exp) while(mwAssert((int)(exp),#exp,__FILE__,__LINE__))
|
554
|
+
#ifndef MW_NOASSERT
|
555
|
+
#ifndef ASSERT
|
556
|
+
#define ASSERT mwASSERT
|
557
|
+
#endif /* !ASSERT */
|
558
|
+
#endif /* !MW_NOASSERT */
|
559
|
+
#define mwVERIFY(exp) while(mwVerify((int)(exp),#exp,__FILE__,__LINE__))
|
560
|
+
#ifndef MW_NOVERIFY
|
561
|
+
#ifndef VERIFY
|
562
|
+
#define VERIFY mwVERIFY
|
563
|
+
#endif /* !VERIFY */
|
564
|
+
#endif /* !MW_NOVERIFY */
|
565
|
+
#define mwTRACE mwTrace
|
566
|
+
#ifndef MW_NOTRACE
|
567
|
+
#ifndef TRACE
|
568
|
+
#define TRACE mwTRACE
|
569
|
+
#endif /* !TRACE */
|
570
|
+
#endif /* !MW_NOTRACE */
|
571
|
+
|
572
|
+
/* some compilers use a define and not a function */
|
573
|
+
/* for strdup(). */
|
574
|
+
#ifdef strdup
|
575
|
+
#undef strdup
|
576
|
+
#endif
|
577
|
+
|
578
|
+
#define malloc(n) mwMalloc(n,__FILE__,__LINE__)
|
579
|
+
#define strdup(p) mwStrdup(p,__FILE__,__LINE__)
|
580
|
+
#define realloc(p,n) mwRealloc(p,n,__FILE__,__LINE__)
|
581
|
+
#define calloc(n,m) mwCalloc(n,m,__FILE__,__LINE__)
|
582
|
+
#define free(p) mwFree(p,__FILE__,__LINE__)
|
583
|
+
#define CHECK() mwTest(__FILE__,__LINE__,MW_TEST_ALL)
|
584
|
+
#define CHECK_THIS(n) mwTest(__FILE__,__LINE__,n)
|
585
|
+
#define CHECK_BUFFER(b) mwTestBuffer(__FILE__,__LINE__,b)
|
586
|
+
#define MARK(p) mwMark(p,#p,__FILE__,__LINE__)
|
587
|
+
#define UNMARK(p) mwUnmark(p,__FILE__,__LINE__)
|
588
|
+
|
589
|
+
#else /* MEMWATCH */
|
590
|
+
|
591
|
+
#define mwASSERT(exp)
|
592
|
+
#ifndef MW_NOASSERT
|
593
|
+
#ifndef ASSERT
|
594
|
+
#define ASSERT mwASSERT
|
595
|
+
#endif /* !ASSERT */
|
596
|
+
#endif /* !MW_NOASSERT */
|
597
|
+
|
598
|
+
#define mwVERIFY(exp) exp
|
599
|
+
#ifndef MW_NOVERIFY
|
600
|
+
#ifndef VERIFY
|
601
|
+
#define VERIFY mwVERIFY
|
602
|
+
#endif /* !VERIFY */
|
603
|
+
#endif /* !MW_NOVERIFY */
|
604
|
+
|
605
|
+
/*lint -esym(773,mwTRACE) */
|
606
|
+
#define mwTRACE /*lint -save -e506 */ 1?(void)0:mwDummyTraceFunction /*lint -restore */
|
607
|
+
#ifndef MW_NOTRACE
|
608
|
+
#ifndef TRACE
|
609
|
+
/*lint -esym(773,TRACE) */
|
610
|
+
#define TRACE mwTRACE
|
611
|
+
#endif /* !TRACE */
|
612
|
+
#endif /* !MW_NOTRACE */
|
613
|
+
|
614
|
+
extern void mwDummyTraceFunction(const char *,...);
|
615
|
+
/*lint -save -e652 */
|
616
|
+
#define mwDoFlush(n)
|
617
|
+
#define mwPuts(s)
|
618
|
+
#define mwInit()
|
619
|
+
#define mwGrab(n)
|
620
|
+
#define mwDrop(n)
|
621
|
+
#define mwLimit(n)
|
622
|
+
#define mwTest(f,l)
|
623
|
+
#define mwSetOutFunc(f)
|
624
|
+
#define mwSetAriFunc(f)
|
625
|
+
#define mwDefaultAri()
|
626
|
+
#define mwNomansland()
|
627
|
+
#define mwStatistics(f)
|
628
|
+
#define mwMark(p,t,f,n) (p)
|
629
|
+
#define mwUnmark(p,f,n) (p)
|
630
|
+
#define mwMalloc(n,f,l) malloc(n)
|
631
|
+
#define mwStrdup(p,f,l) strdup(p)
|
632
|
+
#define mwRealloc(p,n,f,l) realloc(p,n)
|
633
|
+
#define mwCalloc(n,m,f,l) calloc(n,m)
|
634
|
+
#define mwFree(p) free(p)
|
635
|
+
#define mwMalloc_(n) malloc(n)
|
636
|
+
#define mwRealloc_(p,n) realloc(p,n)
|
637
|
+
#define mwCalloc_(n,m) calloc(n,m)
|
638
|
+
#define mwFree_(p) free(p)
|
639
|
+
#define mwAssert(e,es,f,l)
|
640
|
+
#define mwVerify(e,es,f,l) (e)
|
641
|
+
#define mwTrace mwDummyTrace
|
642
|
+
#define mwTestBuffer(f,l,b) (0)
|
643
|
+
#define CHECK()
|
644
|
+
#define CHECK_THIS(n)
|
645
|
+
#define CHECK_BUFFER(b)
|
646
|
+
#define MARK(p) (p)
|
647
|
+
#define UNMARK(p) (p)
|
648
|
+
/*lint -restore */
|
649
|
+
|
650
|
+
#endif /* MEMWATCH */
|
651
|
+
#endif /* !__MEMWATCH_C */
|
652
|
+
|
653
|
+
#ifdef __cplusplus
|
654
|
+
}
|
655
|
+
#endif
|
656
|
+
|
657
|
+
#if 0 /* 980317: disabled C++ */
|
658
|
+
|
659
|
+
/*
|
660
|
+
** C++ support section
|
661
|
+
** Implements the C++ support. Please note that in order to avoid
|
662
|
+
** messing up library classes, C++ support is disabled by default.
|
663
|
+
** You must NOT enable it until AFTER the inclusion of all header
|
664
|
+
** files belonging to code that are not compiled with MEMWATCH, and
|
665
|
+
** possibly for some that are! The reason for this is that a C++
|
666
|
+
** class may implement it's own new() function, and the preprocessor
|
667
|
+
** would substitute this crucial declaration for MEMWATCH new().
|
668
|
+
** You can forcibly deny C++ support by defining MEMWATCH_NOCPP.
|
669
|
+
** To enble C++ support, you must be compiling C++, MEMWATCH must
|
670
|
+
** be defined, MEMWATCH_NOCPP must not be defined, and finally,
|
671
|
+
** you must define 'new' to be 'mwNew', and 'delete' to be 'mwDelete'.
|
672
|
+
** Unlike C, C++ code can begin executing *way* before main(), for
|
673
|
+
** example if a global variable is created. For this reason, you can
|
674
|
+
** declare a global variable of the class 'MemWatch'. If this is
|
675
|
+
** is the first variable created, it will then check ALL C++ allocations
|
676
|
+
** and deallocations. Unfortunately, this evaluation order is not
|
677
|
+
** guaranteed by C++, though the compilers I've tried evaluates them
|
678
|
+
** in the order encountered.
|
679
|
+
*/
|
680
|
+
#ifdef __cplusplus
|
681
|
+
#ifndef __MEMWATCH_C
|
682
|
+
#ifdef MEMWATCH
|
683
|
+
#ifndef MEMWATCH_NOCPP
|
684
|
+
extern int mwNCur;
|
685
|
+
extern const char *mwNFile;
|
686
|
+
extern int mwNLine;
|
687
|
+
class MemWatch {
|
688
|
+
public:
|
689
|
+
MemWatch();
|
690
|
+
~MemWatch();
|
691
|
+
};
|
692
|
+
void * operator new(size_t);
|
693
|
+
void * operator new(size_t,const char *,int);
|
694
|
+
void * operator new[] (size_t,const char *,int); // hjc 07/16/02
|
695
|
+
void operator delete(void *);
|
696
|
+
#define mwNew new(__FILE__,__LINE__)
|
697
|
+
#define mwDelete (mwNCur=1,mwNFile=__FILE__,mwNLine=__LINE__),delete
|
698
|
+
#endif /* MEMWATCH_NOCPP */
|
699
|
+
#endif /* MEMWATCH */
|
700
|
+
#endif /* !__MEMWATCH_C */
|
701
|
+
#endif /* __cplusplus */
|
702
|
+
|
703
|
+
#endif /* 980317: disabled C++ */
|
704
|
+
|
705
|
+
#endif /* __MEMWATCH_H */
|
706
|
+
|
707
|
+
/* EOF MEMWATCH.H */
|