1 #ifndef MPT_DMALLOC_H
2 #define MPT_DMALLOC_H
3 
4 
5 /*
6  * mpatrol
7  * A library for controlling and tracing dynamic memory allocations.
8  * Copyright (C) 1997-2002 Graeme S. Roy <graeme.roy@analog.com>
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public
21  * License along with this library; if not, write to the Free
22  * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23  * MA 02111-1307, USA.
24  */
25 
26 
27 /*
28  * Dmalloc-compatible interface.  Implements Dmalloc functions using
29  * mpatrol.  Dmalloc is copyright (C) 1992-2001 Gray Watson.
30  */
31 
32 
33 /*
34  * $Id: dmalloc.h,v 1.12 2002/01/08 20:05:10 graeme Exp $
35  */
36 
37 
38 /*
39  * This file provides Dmalloc-compatible functions which are built on top
40  * of the mpatrol library.  They are compatible with the 4.8.2 release of
41  * Dmalloc, but only the Dmalloc-specific functions are defined here,
42  * leaving the overriding of standard functions up to the mpatrol library.
43  * As the mpatrol library does not currently override the C library
44  * string functions, neither does this file.  In addition, the Dmalloc
45  * distribution comes with definitions for xmemalign(), xvalloc() and
46  * xrecalloc(), neither of which are defined by this file or by the
47  * mpatrol library.
48  *
49  * This module is intended to work with the existing dmalloc command,
50  * which sets the contents of the DMALLOC_OPTIONS environment variable
51  * according to any specified command line options.  The four documented
52  * Dmalloc global variables are also defined, although the two address
53  * variables are not acted upon and changing the dmalloc_logpath variable
54  * has no effect yet.  The dmalloc_errno variable is mapped onto the
55  * __mp_errno variable and so the dmalloc_strerror() function always
56  * returns strings that are specific to the mpatrol library.  Note that
57  * unlike the actual Dmalloc library, this file is not threadsafe, and the
58  * lockon option has no effect.  In addition, the start option ignores the
59  * file:line syntax and uses allocation indices rather than events.
60  *
61  * The dmalloc_debug() function does not support the setting of all of the
62  * Dmalloc flags, although this file defines preprocessor macros for each
63  * of them, something which is not currently done in the dmalloc.h file in
64  * the Dmalloc distribution.  In fact, many of them do not make sense when
65  * applied to the mpatrol library.  Some of them have slightly changed
66  * behaviour due to the mapping process and some of them cannot be
67  * implemented due to the mpatrol library having been initialised
68  * beforehand.
69  *
70  * The dmalloc_verify() and dmalloc_examine() functions do not give an
71  * error message if the pointer passed in does not correspond to a heap
72  * allocation, and the latter function does not automatically perform an
73  * integrity check of the heap.  The malloc_verify() function has not been
74  * included in this implementation since it is functionally identical to
75  * dmalloc_verify().  Note that the dmalloc_verify() function will only
76  * ever return DMALLOC_VERIFY_ERROR if the pointer to be checked is not
77  * null and is invalid - it always terminates with an error message in the
78  * mpatrol log file whenever the pointer to be checked is null and it has
79  * detected heap corruption.
80  *
81  * The dmalloc_log_heap_map() and dmalloc_log_stats() functions map on to
82  * the __mp_memorymap() and __mp_summary() functions and so have entirely
83  * different display formats.  The dmalloc_log_unfreed() and
84  * dmalloc_log_changed() functions have similar display formats to the
85  * original Dmalloc library, but the summary tables are displayed
86  * differently and will display symbol names if they are available and
87  * filename and line number information isn't.  The dmalloc_message() and
88  * dmalloc_vmessage() functions write tracing to the mpatrol log file
89  * prefixed by three fields of optional information, which can be
90  * controlled by the LOG_* macros when building this module.
91  *
92  * This file is initialised via the mpatrol library's initialiser function
93  * feature, which means that if the __mp_init_dmalloc() function is noted
94  * by the mpatrol symbol manager then it will be called when the mpatrol
95  * library is being initialised.  If this feature is not supported then
96  * the dmalloc_init() function must be called as early on as possible,
97  * otherwise this file will not be initialised until one of its functions
98  * are called.
99  */
100 
101 
102 #include <mpatrol.h>
103 
104 
105 /* The version of Dmalloc that this file is simulating and is compatible with.
106  */
107 
108 #define DMALLOC_VERSION_MAJOR 4
109 #define DMALLOC_VERSION_MINOR 8
110 #define DMALLOC_VERSION_PATCH 2
111 #define DMALLOC_VERSION_BETA  0
112 
113 
114 /* The return codes from dmalloc_examine() and dmalloc_verify().
115  */
116 
117 #define DMALLOC_ERROR          0
118 #define DMALLOC_NOERROR        1
119 #define DMALLOC_VERIFY_ERROR   0
120 #define DMALLOC_VERIFY_NOERROR 1
121 
122 
123 /* The library flags that can be set with dmalloc_debug().  They are not
124  * currently defined in dmalloc.h in the original Dmalloc distribution but
125  * dmalloc_debug() is pretty much useless without them.
126  */
127 
128 #define DMALLOC_LOG_STATS         0x00000001
129 #define DMALLOC_LOG_NONFREE       0x00000002
130 #define DMALLOC_LOG_KNOWN         0x00000004
131 #define DMALLOC_LOG_TRANS         0x00000008
132 #define DMALLOC_LOG_ADMIN         0x00000020
133 #define DMALLOC_LOG_BLOCKS        0x00000040
134 #define DMALLOC_LOG_BAD_SPACE     0x00000100
135 #define DMALLOC_LOG_NONFREE_SPACE 0x00000200
136 #define DMALLOC_CHECK_FENCE       0x00000400
137 #define DMALLOC_CHECK_HEAP        0x00000800
138 #define DMALLOC_CHECK_LISTS       0x00001000
139 #define DMALLOC_CHECK_BLANK       0x00002000
140 #define DMALLOC_CHECK_FUNCS       0x00004000
141 #define DMALLOC_FORCE_LINEAR      0x00010000
142 #define DMALLOC_CATCH_SIGNALS     0x00020000
143 #define DMALLOC_LOG_ELAPSED_TIME  0x00040000
144 #define DMALLOC_LOG_CURRENT_TIME  0x00080000
145 #define DMALLOC_REALLOC_COPY      0x00100000
146 #define DMALLOC_FREE_BLANK        0x00200000
147 #define DMALLOC_ERROR_ABORT       0x00400000
148 #define DMALLOC_ALLOC_BLANK       0x00800000
149 #define DMALLOC_HEAP_CHECK_MAP    0x01000000
150 #define DMALLOC_PRINT_MESSAGES    0x02000000
151 #define DMALLOC_CATCH_NULL        0x04000000
152 #define DMALLOC_NEVER_REUSE       0x08000000
153 #define DMALLOC_ALLOW_FREE_NULL   0x20000000
154 #define DMALLOC_ERROR_DUMP        0x40000000
155 
156 
157 /* The different function types that can be passed to the callback function
158  * registered with dmalloc_track().
159  */
160 
161 #define DMALLOC_FUNC_MALLOC   MP_AT_MALLOC
162 #define DMALLOC_FUNC_CALLOC   MP_AT_CALLOC
163 #define DMALLOC_FUNC_MEMALIGN MP_AT_MEMALIGN
164 #define DMALLOC_FUNC_VALLOC   MP_AT_VALLOC
165 #define DMALLOC_FUNC_STRDUP   MP_AT_STRDUP
166 #define DMALLOC_FUNC_REALLOC  MP_AT_REALLOC
167 #define DMALLOC_FUNC_RECALLOC MP_AT_RECALLOC
168 #define DMALLOC_FUNC_FREE     MP_AT_FREE
169 
170 
171 /* The type for any callback function that is registered with dmalloc_track().
172  */
173 
174 typedef void (*dmalloc_track_t)(MP_CONST char *, unsigned long, int, size_t,
175                                 size_t, MP_CONST void *, MP_CONST void *);
176 
177 
178 #ifndef NDEBUG
179 
180 #define dmalloc_errno __mp_errno
181 
182 #define dmalloc_init() __mp_init_dmalloc()
183 #define dmalloc_shutdown() __mpt_dmallocshutdown()
184 #define dmalloc_log_heap_map() __mp_memorymap(0)
185 #define dmalloc_log_stats() __mp_summary()
186 #define dmalloc_log_unfreed() __mpt_dmalloclogchanged(0, 1, 0, 1)
187 #define dmalloc_verify(p) __mpt_dmallocverify((p), MP_FUNCNAME, __FILE__, \
188                                               __LINE__)
189 #define dmalloc_debug(f) __mpt_dmallocdebug(f)
190 #define dmalloc_debug_current() __mpt_dmallocdebugcurrent()
191 #define dmalloc_examine(p, l, t, u, a) __mpt_dmallocexamine((p), (l), (t), \
192                                                             (u), (a))
193 #define dmalloc_message __mpt_dmallocmessage
194 #define dmalloc_vmessage(s, v) __mpt_dmallocvmessage((s), (v))
195 #define dmalloc_track(h) __mpt_dmalloctrack(h)
196 #define dmalloc_mark() __mp_snapshot()
197 #define dmalloc_log_changed(m, u, f, d) __mpt_dmalloclogchanged((m), (u), (f), \
198                                                                 (d))
199 #define dmalloc_strerror(e) __mpt_dmallocstrerror(e)
200 
201 
202 #ifdef __cplusplus
203 extern "C"
204 {
205 #endif /* __cplusplus */
206 
207 
208 extern char *dmalloc_logpath;
209 extern void *dmalloc_address;
210 extern unsigned long dmalloc_address_count;
211 
212 
213 void __mpt_dmallocshutdown(void);
214 int __mpt_dmallocverify(MP_CONST void *, MP_CONST char *, MP_CONST char *,
215                         unsigned long);
216 unsigned long __mpt_dmallocdebug(unsigned long);
217 unsigned long __mpt_dmallocdebugcurrent(void);
218 int __mpt_dmallocexamine(MP_CONST void *, size_t *, char **, unsigned long *,
219                          void **);
220 void __mpt_dmallocmessage(MP_CONST char *, ...);
221 void __mpt_dmallocvmessage(MP_CONST char *, va_list);
222 void __mpt_dmalloctrack(dmalloc_track_t);
223 void __mpt_dmalloclogchanged(unsigned long, int, int, int);
224 MP_CONST char *__mpt_dmallocstrerror(__mp_errortype);
225 void __mp_init_dmalloc(void);
226 
227 
228 static MP_VOLATILE void *__mpt_init_dmalloc = (void *) __mp_init_dmalloc;
229 
230 
231 #ifdef __cplusplus
232 }
233 #endif /* __cplusplus */
234 
235 #else /* NDEBUG */
236 
237 #define dmalloc_errno __mp_errno
238 
239 #define dmalloc_init() ((void) 0)
240 #define dmalloc_shutdown() ((void) 0)
241 #define dmalloc_log_heap_map() ((void) 0)
242 #define dmalloc_log_stats() ((void) 0)
243 #define dmalloc_log_unfreed() ((void) 0)
244 #define dmalloc_verify(p) ((int) 1)
245 #define dmalloc_debug(f) ((unsigned long) 0)
246 #define dmalloc_debug_current() ((unsigned long) 0)
247 #define dmalloc_examine(p, l, t, u, a) ((int) 0)
248 #define dmalloc_vmessage(s, v) ((void) 0)
249 #define dmalloc_track(h) ((void) 0)
250 #define dmalloc_mark() ((unsigned long) 0)
251 #define dmalloc_log_changed(m, u, f, d) ((void) 0)
252 #define dmalloc_strerror(e) "errno value is not valid"
253 
254 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ == 199901L)
255 #define dmalloc_message(...) ((void) 0)
256 #elif defined(__GNUC__)
257 #define dmalloc_message(a...) ((void) 0)
258 #else /* __STDC_VERSION__ && __GNUC__ */
259 static
260 void
dmalloc_message(MP_CONST char * s,...)261 dmalloc_message(MP_CONST char *s, ...)
262 {
263 }
264 #endif /* __STDC_VERSION__ && __GNUC__ */
265 
266 #endif /* NDEBUG */
267 
268 
269 #endif /* MPT_DMALLOC_H */
270