1 #ifndef MP_INFO_H
2 #define MP_INFO_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  * Allocation information.  The high-level details of every memory
29  * allocation are stored by this module, while the low-level details
30  * are dealt with by the memory allocation module.
31  */
32 
33 
34 /*
35  * $Id: info.h,v 1.69 2002/01/08 20:13:59 graeme Exp $
36  */
37 
38 
39 #include "config.h"
40 #include "alloc.h"
41 #include "addr.h"
42 #include "leaktab.h"
43 #include "profile.h"
44 #include "trace.h"
45 #include "signals.h"
46 
47 
48 #define FLG_CHECKALLOCS   0x00000001 /* check all memory allocations */
49 #define FLG_CHECKREALLOCS 0x00000002 /* check all memory reallocations */
50 #define FLG_CHECKFREES    0x00000004 /* check all memory deallocations */
51 #define FLG_CHECKMEMORY   0x00000008 /* check all memory operations */
52 #define FLG_LOGALLOCS     0x00000010 /* log all memory allocations */
53 #define FLG_LOGREALLOCS   0x00000020 /* log all memory reallocations */
54 #define FLG_LOGFREES      0x00000040 /* log all memory deallocations */
55 #define FLG_LOGMEMORY     0x00000080 /* log all memory operations */
56 #define FLG_SHOWFREE      0x00000100 /* show all free blocks */
57 #define FLG_SHOWFREED     0x00000200 /* show all freed allocations */
58 #define FLG_SHOWUNFREED   0x00000400 /* show all unfreed allocations */
59 #define FLG_SHOWMAP       0x00000800 /* show memory map of heap */
60 #define FLG_SHOWSYMBOLS   0x00001000 /* show all symbols read */
61 #define FLG_LEAKTABLE     0x00002000 /* automatically use the leak table */
62 #define FLG_ALLOWOFLOW    0x00004000 /* allow memory operations to overflow */
63 #define FLG_SAFESIGNALS   0x00008000 /* save and restore signal handlers */
64 #define FLG_NOPROTECT     0x00010000 /* do not protect internal structures */
65 #define FLG_CHECKFORK     0x00020000 /* check for forked processes */
66 
67 #define FLG_FREED         0x00000001 /* allocation has been freed */
68 #define FLG_MARKED        0x00000002 /* allocation has been marked */
69 #define FLG_PROFILED      0x00000004 /* allocation has been profiled */
70 #define FLG_TRACED        0x00000008 /* allocation has been traced */
71 #define FLG_INTERNAL      0x00000010 /* allocation was made inside mpatrol */
72 
73 
74 /* The types of the prologue, epilogue and low memory handlers.
75  */
76 
77 typedef void (*prologuehandler)(void *, size_t, size_t, char *, char *,
78                                 unsigned long, void *);
79 typedef void (*epiloguehandler)(void *, char *, char *, unsigned long, void *);
80 typedef void (*nomemoryhandler)(char *, char *, unsigned long, void *);
81 
82 
83 /* The different types of memory allocation and operation functions.
84  * This must be kept up to date with the definition of __mp_alloctype
85  * in mpatrol.h.
86  */
87 
88 typedef enum alloctype
89 {
90     AT_MALLOC,    /* malloc() */
91     AT_CALLOC,    /* calloc() */
92     AT_MEMALIGN,  /* memalign() */
93     AT_VALLOC,    /* valloc() */
94     AT_PVALLOC,   /* pvalloc() */
95     AT_ALLOCA,    /* alloca() */
96     AT_STRDUP,    /* strdup() */
97     AT_STRNDUP,   /* strndup() */
98     AT_STRSAVE,   /* strsave() */
99     AT_STRNSAVE,  /* strnsave() */
100     AT_STRDUPA,   /* strdupa() */
101     AT_STRNDUPA,  /* strndupa() */
102     AT_REALLOC,   /* realloc() */
103     AT_REALLOCF,  /* reallocf() */
104     AT_RECALLOC,  /* recalloc() */
105     AT_EXPAND,    /* expand() */
106     AT_FREE,      /* free() */
107     AT_CFREE,     /* cfree() */
108     AT_DEALLOCA,  /* dealloca() */
109     AT_XMALLOC,   /* xmalloc() */
110     AT_XCALLOC,   /* xcalloc() */
111     AT_XSTRDUP,   /* xstrdup() */
112     AT_XREALLOC,  /* xrealloc() */
113     AT_XFREE,     /* xfree() */
114     AT_NEW,       /* operator new */
115     AT_NEWVEC,    /* operator new[] */
116     AT_DELETE,    /* operator delete */
117     AT_DELETEVEC, /* operator delete[] */
118     AT_MEMSET,    /* memset() */
119     AT_BZERO,     /* bzero() */
120     AT_MEMCCPY,   /* memccpy() */
121     AT_MEMCPY,    /* memcpy() */
122     AT_MEMMOVE,   /* memmove() */
123     AT_BCOPY,     /* bcopy() */
124     AT_MEMCHR,    /* memchr() */
125     AT_MEMMEM,    /* memmem() */
126     AT_MEMCMP,    /* memcmp() */
127     AT_BCMP,      /* bcmp() */
128     AT_MAX
129 }
130 alloctype;
131 
132 
133 /* The overall types of memory allocation and operation functions for logging
134  * purposes.
135  */
136 
137 typedef enum logtype
138 {
139     LT_ALLOC,   /* memory allocation */
140     LT_REALLOC, /* memory reallocation */
141     LT_FREE,    /* memory deallocation */
142     LT_SET,     /* memory set */
143     LT_COPY,    /* memory copy */
144     LT_LOCATE,  /* memory search */
145     LT_COMPARE, /* memory comparison */
146     LT_MAX
147 }
148 logtype;
149 
150 
151 /* An allocanode belongs to a stack of memory allocations that were made
152  * by the alloca() and related functions.  Some memory allocations at the
153  * top of the stack may be automatically freed when the next call to an
154  * mpatrol function is made and the stack has been unwound.
155  */
156 
157 typedef struct allocanode
158 {
159     listnode node;   /* list node */
160     void *block;     /* pointer to block of memory */
161     union
162     {
163         size_t size; /* size of block of memory */
164         void *frame; /* pointer to stack frame */
165     }
166     data;
167 }
168 allocanode;
169 
170 
171 /* A loginfo structure is used to pass around information about a calling
172  * function.
173  */
174 
175 typedef struct loginfo
176 {
177     logtype ltype;              /* overall type of memory allocation */
178     union
179     {
180         struct
181         {
182             size_t size;        /* size */
183             size_t align;       /* alignment */
184         }
185         logalloc;
186         struct
187         {
188             void *block;        /* memory block */
189             size_t size;        /* size */
190             size_t align;       /* alignment */
191         }
192         logrealloc;
193         struct
194         {
195             void *block;        /* memory block */
196         }
197         logfree;
198         struct
199         {
200             void *block;        /* memory block */
201             size_t size;        /* size */
202             unsigned char byte; /* filler byte */
203         }
204         logmemset;
205         struct
206         {
207             void *srcblock;     /* source memory block */
208             void *dstblock;     /* destination memory block */
209             size_t size;        /* size */
210             unsigned char byte; /* stop byte */
211         }
212         logmemcopy;
213         struct
214         {
215             void *block;        /* memory block */
216             size_t size;        /* size */
217             void *patblock;     /* pattern memory block */
218             size_t patsize;     /* pattern size */
219         }
220         logmemlocate;
221         struct
222         {
223             void *block1;       /* memory block 1 */
224             void *block2;       /* memory block 2 */
225             size_t size;        /* size */
226         }
227         logmemcompare;
228     }
229     variant;
230     alloctype type;             /* type of memory allocation */
231     char *func;                 /* calling function name */
232     char *file;                 /* file name in which call took place */
233     unsigned long line;         /* line number at which call took place */
234     stackinfo *stack;           /* call stack details */
235     char *typestr;              /* type stored in allocation */
236     size_t typesize;            /* size of type stored in allocation */
237     char logged;                /* logged flag */
238 }
239 loginfo;
240 
241 
242 /* The structure used to record source level information about recursive
243  * calls to C++ operator delete and operator delete[].
244  */
245 
246 typedef struct delstack
247 {
248     char *func;         /* calling function name */
249     char *file;         /* file name in which call took place */
250     unsigned long line; /* line number at which call took place */
251 }
252 delstack;
253 
254 
255 /* An allocation information node belongs to a table of nodes, although
256  * details of internal memory allocations are also stored in allocation
257  * information nodes as part of a list.
258  */
259 
260 typedef union infonode
261 {
262     struct
263     {
264         listnode node;         /* internal list node */
265         void *block;           /* pointer to block of memory */
266         size_t size;           /* size of block of memory */
267     }
268     index;
269     struct
270     {
271         alloctype type;        /* type of memory allocation */
272         unsigned long alloc;   /* allocation index */
273         unsigned long realloc; /* reallocation index */
274 #if MP_THREADS_SUPPORT
275         unsigned long thread;  /* thread identifier */
276 #endif /* MP_THREADS_SUPPORT */
277         unsigned long event;   /* event of last modification */
278         char *func;            /* calling function name */
279         char *file;            /* file name in which call took place */
280         unsigned long line;    /* line number at which call took place */
281         addrnode *stack;       /* call stack details */
282         char *typestr;         /* type stored in allocation */
283         size_t typesize;       /* size of type stored in allocation */
284         void *userdata;        /* user data associated with allocation */
285         unsigned long flags;   /* allocation flags */
286     }
287     data;
288 }
289 infonode;
290 
291 
292 /* An infohead holds the table of allocation information nodes as well
293  * as all of the other data structures used by the mpatrol library.
294  */
295 
296 typedef struct infohead
297 {
298     allochead alloc;                  /* allocation table */
299     addrhead addr;                    /* stack address table */
300     symhead syms;                     /* symbol table */
301     sighead signals;                  /* signal handler table */
302     leaktab ltable;                   /* leak table */
303     profhead prof;                    /* profiling information */
304     tracehead trace;                  /* tracing information */
305     slottable table;                  /* table of information nodes */
306     slottable atable;                 /* table of allocanodes */
307     listhead list;                    /* internal allocation list */
308     listhead alist;                   /* internal allocanode list */
309     listhead astack;                  /* alloca allocation stack */
310     size_t size;                      /* internal allocation total */
311     size_t event;                     /* allocation event count */
312     size_t count;                     /* allocation count */
313     size_t cpeak;                     /* allocation count peak */
314     size_t peak;                      /* allocation peak */
315     size_t limit;                     /* allocation limit */
316     size_t astop;                     /* allocation stop index */
317     size_t rstop;                     /* reallocation stop index */
318     size_t fstop;                     /* free stop index */
319     size_t uabort;                    /* unfreed abort minimum */
320     size_t lrange;                    /* lower check range */
321     size_t urange;                    /* upper check range */
322     size_t check;                     /* check frequency */
323     size_t mcount;                    /* marked allocation count */
324     size_t mtotal;                    /* total bytes marked */
325     size_t dtotal;                    /* total bytes compared */
326     size_t ltotal;                    /* total bytes located */
327     size_t ctotal;                    /* total bytes copied */
328     size_t stotal;                    /* total bytes set */
329     unsigned long ffreq;              /* failure frequency */
330     unsigned long fseed;              /* failure seed */
331     prologuehandler prologue;         /* prologue function */
332     epiloguehandler epilogue;         /* epilogue function */
333     nomemoryhandler nomemory;         /* low-memory handler function */
334     void (*inits[MP_MAXINITS])(void); /* initialisation functions */
335     size_t initcount;                 /* initialisation function count */
336     void (*finis[MP_MAXFINIS])(void); /* finalisation functions */
337     size_t finicount;                 /* finalisation function count */
338     char *log;                        /* log filename */
339     delstack dels[MP_MAXDELSTACK];    /* delete stack */
340     long delpos;                      /* delete stack pointer */
341     unsigned long flags;              /* global flags */
342     unsigned long pid;                /* process identifier */
343     memaccess prot;                   /* protection status */
344     size_t recur;                     /* recursion count */
345     char init;                        /* initialisation flag */
346     char fini;                        /* finalisation flag */
347 }
348 infohead;
349 
350 
351 #ifdef __cplusplus
352 extern "C"
353 {
354 #endif /* __cplusplus */
355 
356 
357 MP_EXPORT void __mp_newinfo(infohead *);
358 MP_EXPORT void __mp_deleteinfo(infohead *);
359 MP_EXPORT int __mp_atinit(infohead *, void (*)(void));
360 MP_EXPORT int __mp_atfini(infohead *, void (*)(void));
361 MP_EXPORT void *__mp_getmemory(infohead *, size_t, size_t, loginfo *);
362 MP_EXPORT void *__mp_resizememory(infohead *, void *, size_t, size_t,
363                                   loginfo *);
364 MP_EXPORT void __mp_freememory(infohead *, void *, loginfo *);
365 MP_EXPORT void __mp_setmemory(infohead *, void *, size_t, unsigned char,
366                               loginfo *);
367 MP_EXPORT void *__mp_copymemory(infohead *, void *, void *, size_t,
368                                 unsigned char, loginfo *);
369 MP_EXPORT void *__mp_locatememory(infohead *, void *, size_t, void *, size_t,
370                                   loginfo *);
371 MP_EXPORT int __mp_comparememory(infohead *, void *, void *, size_t, loginfo *);
372 MP_EXPORT int __mp_protectinfo(infohead *, memaccess);
373 MP_EXPORT void __mp_checkinfo(infohead *, loginfo *);
374 MP_EXPORT int __mp_checkrange(infohead *, void *, size_t, loginfo *);
375 MP_EXPORT int __mp_checkstring(infohead *, char *, size_t *, loginfo *, int);
376 MP_EXPORT size_t __mp_fixalign(infohead *, alloctype, size_t);
377 
378 
379 #ifdef __cplusplus
380 }
381 #endif /* __cplusplus */
382 
383 
384 #endif /* MP_INFO_H */
385