]>
Commit | Line | Data |
---|---|---|
189935b1 | 1 | fdaman.txt - brief usage information for FDA (Free Debug Allocator) |
2 | ||
3 | Copyright (C) 1998 Thomas Helvey <tomh@inxpress.net> | |
4 | ||
5 | 1. Base Functionality | |
6 | Basic use of the fda tools is as simple as including the header | |
7 | and source file with your source defining DEBUG and using capitalized | |
8 | versions of malloc(), calloc(), realloc(), and free(). | |
9 | The fda allocation functions verify all your arguments and will call | |
10 | assert() if something is wrong. FDA trashes all allocated memory | |
11 | in a predictable manner and applies prefix and postfix bounds checking | |
12 | signatures to every allocation. When a pointer is freed it's validated, | |
13 | and checked for overflows and underflows. The fda Realloc function | |
14 | does not allow malloc or free through realloc and forces reallocation | |
15 | if the required memory is larger than the current allocation. | |
16 | ||
17 | In both the DEBUG and non-debug versions of fda, if a memory allocation | |
18 | fails once, a low memory callback function is called to allow you to | |
19 | release some memory and allow malloc to succeed, the default version | |
20 | prints a warning message to stderr. If the low memory callback returns | |
21 | the allocation is attempted again, if the second allocation fails a | |
22 | no memory callback function is called to allow you to clean up before | |
23 | terminating the application, if you allow the no memory callback to | |
24 | return the results are undefined. (a NULL ptr will be returned from the | |
25 | allocation call) The default no memory handler prints an error message | |
26 | to stderr and calls abort(). The DEBUG version will assert if you allow | |
27 | the no memory function to return. | |
28 | Both the low memory and no memory callbacks have the signature of: | |
29 | void handler(void) | |
30 | ||
31 | The debug version of fda will not allow you to do the following: | |
32 | Allocate a zero length chunk of memory. | |
33 | Free a non-allocated pointer. | |
34 | Free a pointer twice. | |
35 | Free a pointer at the wrong offset. | |
36 | Use realloc to free memory. (realloc(p, 0)) | |
37 | Use realloc to malloc memory. (realloc(0, s)) | |
38 | Overwrite the bounds of the memory you allocated. (checked on free) | |
39 | ||
40 | The base functions for fda are: | |
41 | void* malloc(size_t) | |
42 | void* realloc(void*, size_t) | |
43 | void* calloc(size_t, size_t) | |
44 | void free(void*) | |
45 | char* strdup(const char*) | |
46 | void set_lowmem_handler(void (*fn)(void)) | |
47 | void set_nomem_handler(void (*fn)(void)) | |
48 | ||
49 | FDA uses a hash table to lookup pointers. The size of the hash table can | |
50 | be changed at compile time by using -DFDA_HASH_TABLE_SIZE <prime> | |
51 | where prime is a prime number somewhere around the number of allocations | |
52 | expected. The default hash table size is 16339 which should be large enough | |
53 | to hold most medium sized applications. FDA allocates memory for it's | |
54 | debugging records so if your application uses a lot of memory you | |
55 | may want to make sure you have enough memory available to use the debug | |
56 | version. FDA allocates 20 bytes to store each allocation and 20 bytes | |
57 | to store location information (file and line info). This overhead only | |
58 | applies if you have DEBUG or _DEBUG defined. | |
59 | ||
60 | 2. Extended functionality | |
61 | FDA provides a few handy functions for validating pointers and | |
62 | checking for overruns before they occur when debugging. | |
63 | The first function fda_sizeof(ptr) returns the size of the buffer | |
64 | pointed to by ptr, this allows you to verify that your pointer | |
65 | is what it says it is. fda_sizeof() will call assert() if the | |
66 | pointer you pass it is not at the start of an allocation. | |
67 | ||
68 | The second function valid_ptr(ptr, size) verifies that ptr lies within | |
69 | allocated memory and there are at least size bytes available in the buffer. | |
70 | You can pass valid_ptr() a pointer to any location in allocated memory. | |
71 | valid_ptr() calls assert if the pointer points outside of allocated memory | |
72 | or the remaining size is less than the size specified. | |
73 | valid_ptr() is more efficient if the pointer argument is the value | |
74 | returned from malloc because it's a simple hash table lookup, a more | |
75 | exhaustive algorithm is used if it's not found in the hash table. | |
76 | ||
77 | FDA extended functions: | |
78 | size_t fda_sizeof(const void*) | |
79 | int valid_ptr(const void*, size_t) | |
80 | ||
81 | Typical usage for the fda extended functions: | |
82 | Note: the assert macro compiles to nothing if NDEBUG is defined. | |
83 | Verify a foo_ptr: | |
84 | assert(sizeof(struct foo) == fda_sizeof(foo_ptr)); | |
85 | assert(valid_ptr(foo_ptr, sizeof(struct foo))); | |
86 | Check for room to write: | |
87 | assert(valid_ptr(buf, len)); | |
88 | ||
89 | 3. Leak checking and block validation | |
90 | FDA has several functions for leak checking, and reference marking. | |
91 | fda_clear_refs() iterates through all of the allocated blocks of | |
92 | memory and clears the referenced flag. | |
93 | fda_set_ref() marks a single allocation(block) as being referenced or | |
94 | in use by somebody. | |
95 | fda_assert_refs() iterates through all the allocated blocks of | |
96 | memory and calls assert() if it finds one that's not referenced. | |
97 | ||
98 | Typical usage of the block validation functions: | |
99 | fda_clear_refs(); /* clear all block references */ | |
100 | ||
101 | for each allocation do | |
102 | fda_set_ref(allocation); /* mark allocation in use */ | |
103 | done | |
104 | ||
105 | fda_assert_refs(); /* this will assert if a leak is found */ | |
106 | ||
107 | 4. Reporting functions: | |
108 | FDA has 4 functions for reporting various aspects of allocation | |
109 | status. | |
110 | fda_get_byte_count() tells you the current total number of bytes | |
111 | your application has allocated. (this does not include debugging records) | |
112 | This will give you an idea of how much memory your application is | |
113 | using at any given time. | |
114 | ||
115 | fda_get_block_count() returns the total count of current allocations. | |
116 | ||
117 | fda_enum_locations() calls a user supplied enumeration function with | |
118 | file, line, count information, this allows you to see your file by | |
119 | file allocation density. ;) fda_enum_locations() returns the total | |
120 | number of locations that have memory allocated. | |
121 | ||
122 | fda_enum_leaks() calls a user supplied enumeration function with | |
123 | file, line, size, and ptr for every block not marked as referenced. | |
124 | One use for fda_enum_leaks() is checking for leaks when your program | |
125 | exits: | |
126 | void enum_fn(const char* file, int line, size_t size, void* ptr) | |
127 | { | |
128 | printf("Memory leak: %s: %d - %d bytes at (%p)\n", file, line, size, ptr); | |
129 | } | |
130 | ||
131 | int main(void) | |
132 | { | |
133 | ... | |
134 | #if defined(DEBUG) | |
135 | /* check for memory leaks before exiting */ | |
136 | fda_clear_refs(); | |
137 | fda_enum_leaks(enum_fn); | |
138 | #endif | |
139 | return 0; /* return from main */ | |
140 | } | |
141 | ||
142 | The test file fdatest.c gives examples of usage for most of the functions | |
143 | available with FDA. | |
144 | ||
145 | Please let me know if you encounter any problems with FDA. | |
146 | So far FDA has been built and tested on linux and Windows NT. | |
147 | If you find that it works with or without change on other platforms | |
148 | please let me know so I can make the appropriate changes to the | |
149 | code and add it to the list of tested platforms. | |
150 | ||
151 |