about summary refs log tree commit diff stats
path: root/WWW/Library/Implementation/LYLeaks.h
blob: b3672734db2905ac11d73903726cd0a5501cdca0 (plain) (blame)
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
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
/*
 * $LynxId: LYLeaks.h,v 1.14 2012/02/10 00:15:56 tom Exp $
 */
#ifndef __LYLEAKS_H
/*
 *	Avoid include redundancy
 *	Include only if finding memory leaks.
 */
#define __LYLEAKS_H

/*
 *  Copyright (c) 1994, University of Kansas, All Rights Reserved
 *
 *  Include File:	LYLeaks.h
 *  Purpose:		Header to convert requests for allocation to Lynx
 *			custom functions to track memory leaks.
 *  Remarks/Portability/Dependencies/Restrictions:
 *	For the stdlib.h allocation functions to be overriden by the
 *		Lynx memory tracking functions all modules allocating,
 *		freeing, or resizing memory must have LY_FIND_LEAKS
 *		defined before including this file.
 *	This header file should be included in every source file which
 *		does any memory manipulation through use of the
 *		stdlib.h memory functions.
 *	For proper reporting of memory leaks, the function LYLeaks
 *		should be registered for execution by atexit as the
 *		very first executable statement in main.
 *	This code is slow and should not be used except in debugging
 *		circumstances (don't define LY_FIND_LEAKS).
 *	If you are using LY_FIND_LEAKS and don't want the LYLeak*
 *		memory functions to be used in a certain file,
 *		define NO_MEMORY_TRACKING before including this file.
 *	The only safe way to call the LYLeak* functions is to use
 *		the below macros because they depend on the static
 *		string created by __FILE__ to not be dynamic in
 *		nature (don't free it and assume will exist at all
 *		times during execution).
 *	If you are using LY_FIND_LEAKS and LY_FIND_LEAKS_EXTENDED and
 *		want only normal memory tracking (not extended for
 *		HTSprintf/HTSprintf0) to be used in a certain file,
 *		define NO_EXTENDED_MEMORY_TRACKING and don't define
 *		NO_MEMORY_TRACKING before including this file.
 *  Revision History:
 *	05-26-94	created for Lynx 2-3-1, Garrett Arch Blythe
 *	10-30-97	modified to handle StrAllocCopy() and
 *			StrAllocCat(). - KW & FM
 *	1999-10-17	modified to handle HTSprintf0 and HTSprintf(),
 *			and to provide mark_malloced, if
 *			LY_FIND_LEAKS_EXTENDED is defined. - kw
 *	2003-01-22	add sequence-id for counting mallocs/frees -TD
 *	2004-04-27	ANSIfy'd -TD
 *	2012-02-09	add bstring interfaces -TD
 */

/* Undefine this to get no improved HTSprintf0/HTSprintf tracking: */
#define LY_FIND_LEAKS_EXTENDED

/*
 *  Required includes
 */

#ifndef HTUTILS_H
#include <HTUtils.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif
/*
 *	Constant defines
 */
#define MAX_CONTENT_LENGTH 50
#ifdef VMS
#define LEAKAGE_SINK "sys$login:Lynx.leaks"
#else
#define LEAKAGE_SINK "Lynx.leaks"
#endif				/* VMS */
/*
 * Data structures
 */ typedef struct SourceLocation_tag {
	/*
	 * The file name and line number of where an event took place.
	 */
	const char *cp_FileName;
	short ssi_LineNumber;
    } SourceLocation;

    typedef struct AllocationList_tag {
	/*
	 * A singly linked list.
	 */
	struct AllocationList_tag *ALp_Next;

	/*
	 * Count the number of mallocs.
	 */
	long st_Sequence;

	/*
	 * The memory pointer allocated.  If set to NULL, then an invalid request
	 * was made.  The invalid pointer also.
	 */
	void *vp_Alloced;
	void *vp_BadRequest;

	/*
	 * The size in bytes of the allocated memory.
	 */
	size_t st_Bytes;

	/*
	 * The source location of specific event (calloc, malloc, free).  realloc
	 * kept separate since will track last realloc on pointer.
	 */
	SourceLocation SL_memory;
	SourceLocation SL_realloc;
    } AllocationList;

/*
 *  Global variable declarations
 */

/*
 *  Macros
 */
#if defined(LY_FIND_LEAKS) && !defined(NO_MEMORY_TRACKING)
/*
 * Only use these macros if we are to track memory allocations.  The reason for
 * using a macro instead of a define is that we want to track where the initial
 * allocation took place or where the last reallocation took place.  Track
 * where the allocation took place by the __FILE__ and __LINE__ defines which
 * are automatic to the compiler.
 */
#ifdef malloc
#undef malloc
#endif				/* malloc */
#define malloc(st_bytes) LYLeakMalloc(st_bytes, __FILE__, __LINE__)

#ifdef calloc
#undef calloc
#endif				/* calloc */
#define calloc(st_number, st_bytes) LYLeakCalloc(st_number, st_bytes, \
	__FILE__, __LINE__)

#ifdef realloc
#undef realloc
#endif				/* realloc */
#define realloc(vp_alloced, st_newbytes) LYLeakRealloc(vp_alloced, \
	st_newbytes, __FILE__, __LINE__)

#ifdef free
#undef free
#endif				/* free */
#define free(vp_alloced) LYLeakFree(vp_alloced, __FILE__, __LINE__)

/*
 * Added the following two defines to track Lynx's frequent use of those
 * macros.  - KW 1997-10-12
 */
#ifdef StrAllocCopy
#undef StrAllocCopy
#endif				/* StrAllocCopy */
#define StrAllocCopy(dest, src) LYLeakSACopy(&(dest), src, __FILE__, __LINE__)

#ifdef StrAllocCat
#undef StrAllocCat
#endif				/* StrAllocCat */
#define StrAllocCat(dest, src)  LYLeakSACat(&(dest), src, __FILE__, __LINE__)

#ifdef BStrAlloc
#undef BStrAlloc
#endif
#define BStrAlloc(d,n)   LYLeakSABAlloc( &(d), n, __FILE__, __LINE__)

#ifdef BStrCopy
#undef BStrCopy
#endif
#define BStrCopy(d,s)  LYLeakSABCopy( &(d), BStrData(s), BStrLen(s), __FILE__, __LINE__)

#ifdef BStrCopy0
#undef BStrCopy0
#endif
#define BStrCopy0(d,s)  LYLeakSABCopy0( &(d), s, __FILE__, __LINE__)

#ifdef BStrCat
#undef BStrCat
#endif
#define BStrCat(d,s)  LYLeakSABCat( &(d), BStrData(s), BStrLen(s), __FILE__, __LINE__)

#ifdef BStrCat0
#undef BStrCat0
#endif
#define BStrCat0(d,s)  LYLeakSABCat0( &(d), s, __FILE__, __LINE__)

#define mark_malloced(a,size) LYLeak_mark_malloced(a,size, __FILE__, __LINE__)

#if defined(LY_FIND_LEAKS_EXTENDED) && !defined(NO_EXTENDED_MEMORY_TRACKING)

#ifdef HTSprintf0
#undef HTSprintf0
#endif				/* HTSprintf0 */
#define HTSprintf0 (Get_htsprintf0_fn(__FILE__,__LINE__))

#ifdef HTSprintf
#undef HTSprintf
#endif				/* HTSprintf */
#define HTSprintf (Get_htsprintf_fn(__FILE__,__LINE__))

#endif				/* LY_FIND_LEAKS_EXTENDED and not NO_EXTENDED_MEMORY_TRACKING */

#else				/* LY_FIND_LEAKS && !NO_MEMORY_TRACKING */

#define mark_malloced(a,size)	/* no-op */
#define LYLeakSequence() (-1)

#endif				/* LY_FIND_LEAKS && !NO_MEMORY_TRACKING */

#if defined(LY_FIND_LEAKS)
#define PUBLIC_IF_FIND_LEAKS	/* nothing */
#else
#define PUBLIC_IF_FIND_LEAKS static
#endif

/*
 * Function declarations.
 * See the appropriate source file for usage.
 */
#ifndef LYLeakSequence
    extern long LYLeakSequence(void);
#endif
    extern void LYLeaks(void);

#ifdef LY_FIND_LEAKS_EXTENDED
    extern AllocationList *LYLeak_mark_malloced(void *vp_alloced,
						size_t st_bytes,
						const char *cp_File,
						const short ssi_Line);
#endif				/* LY_FIND_LEAKS_EXTENDED */
    extern void *LYLeakMalloc(size_t st_bytes, const char *cp_File,
			      const short ssi_Line);
    extern void *LYLeakCalloc(size_t st_number, size_t st_bytes, const char *cp_File,
			      const short ssi_Line);
    extern void *LYLeakRealloc(void *vp_alloced,
			       size_t st_newbytes,
			       const char *cp_File,
			       const short ssi_Line);
    extern void LYLeakFree(void *vp_alloced,
			   const char *cp_File,
			   const short ssi_Line);
    extern char *LYLeakSACopy(char **dest,
			      const char *src,
			      const char *cp_File,
			      const short ssi_Line);
    extern char *LYLeakSACat(char **dest,
			     const char *src,
			     const char *cp_File,
			     const short ssi_Line);
    extern void LYLeakSABAlloc(bstring **dest,
			       int len,
			       const char *cp_File,
			       const short ssi_Line);
    extern void LYLeakSABCopy(bstring **dest,
			      const char *src,
			      int len,
			      const char *cp_File,
			      const short ssi_Line);
    extern void LYLeakSABCopy0(bstring **dest,
			       const char *src,
			       const char *cp_File,
			       const short ssi_Line);
    extern void LYLeakSABCat(bstring **dest,
			     const char *src,
			     int len,
			     const char *cp_File,
			     const short ssi_Line);
    extern void LYLeakSABCat0(bstring **dest,
			      const char *src,
			      const char *cp_File,
			      const short ssi_Line);
    extern void LYLeakSABFree(bstring **ptr,
			      const char *cp_File,
			      const short ssi_Line);

#ifdef LY_FIND_LEAKS_EXTENDED
/*
 * Trick to get tracking of var arg functions without relying on var arg
 * preprocessor macros:
 */
    typedef char *HTSprintflike(char **, const char *,...);
    extern HTSprintflike *Get_htsprintf_fn(const char *cp_File,
					   const short ssi_Line);
    extern HTSprintflike *Get_htsprintf0_fn(const char *cp_File,
					    const short ssi_Line);
#endif				/* LY_FIND_LEAKS_EXTENDED */

#ifdef __cplusplus
}
#endif
#endif				/* __LYLEAKS_H */