1 | /******************************************************************* |
---|
2 | * File: omDebug.c |
---|
3 | * Purpose: implementation of main omDebug functions |
---|
4 | * Author: obachman@mathematik.uni-kl.de (Olaf Bachmann) |
---|
5 | * Created: 11/99 |
---|
6 | * Version: $Id: omDebugTrack.c,v 1.16 2002-01-22 16:17:43 Singular Exp $ |
---|
7 | *******************************************************************/ |
---|
8 | #include <mylimits.h> |
---|
9 | #include <string.h> |
---|
10 | #include "omConfig.h" |
---|
11 | #include "omDerivedConfig.h" |
---|
12 | |
---|
13 | #ifdef OM_HAVE_TRACK |
---|
14 | #include "omDefaultConfig.h" |
---|
15 | #include "om_Alloc.h" |
---|
16 | |
---|
17 | /******************************************************************* |
---|
18 | * |
---|
19 | * Declarations |
---|
20 | * |
---|
21 | *******************************************************************/ |
---|
22 | omBinPage om_JustFreedPage = NULL; |
---|
23 | omSpecBin om_SpecTrackBin = NULL; |
---|
24 | |
---|
25 | /* number of bytes for padding before addr: needs to > 0 and a multiple of OM_SIZEOF_STRICT_ALIGNMENT */ |
---|
26 | #ifndef OM_MIN_SIZEOF_FRONT_PATTERN |
---|
27 | #define OM_MIN_SIZEOF_FRONT_PATTERN (OM_MIN_SIZEWOF_FRONT_PATTERN*SIZEOF_STRICT_ALIGNMENT) |
---|
28 | #endif |
---|
29 | /* number of bytes for padding after addr: needs to be a multiple of OM_SIZEOF_STRICT_ALIGNMENT */ |
---|
30 | #ifndef OM_MIN_SIZEOF_BACK_PATTERN |
---|
31 | #define OM_MIN_SIZEOF_BACK_PATTERN (OM_MIN_SIZEWOF_BACK_PATTERN*SIZEOF_STRICT_ALIGNMENT) |
---|
32 | #endif |
---|
33 | |
---|
34 | struct omTrackAddr_s; |
---|
35 | typedef struct omTrackAddr_s omTrackAddr_t; |
---|
36 | typedef omTrackAddr_t * omTrackAddr; |
---|
37 | struct omTrackAddr_s |
---|
38 | { |
---|
39 | void* next; /* reserved for page->current queue */ |
---|
40 | char track; /* > 0; determines size of header */ |
---|
41 | omTrackFlags_t flags; |
---|
42 | #ifdef OM_TRACK_FILE_LINE |
---|
43 | short alloc_line; |
---|
44 | const char* alloc_file; |
---|
45 | #endif |
---|
46 | #ifdef OM_TRACK_RETURN |
---|
47 | const char* alloc_r; |
---|
48 | #endif |
---|
49 | #ifdef OM_TRACK_BACKTRACE |
---|
50 | #define OM_TRACK_ADDR_MEM_1 alloc_frames |
---|
51 | |
---|
52 | /* track > 1 */ |
---|
53 | char* alloc_frames[OM_MAX_KEPT_FRAMES]; |
---|
54 | #else |
---|
55 | #define OM_TRACK_ADDR_MEM_1 bin_size |
---|
56 | #endif |
---|
57 | #define OM_TRACK_ADDR_MEM_2 bin_size |
---|
58 | |
---|
59 | /* track > 2 */ |
---|
60 | void* bin_size; |
---|
61 | #ifdef OM_TRACK_CUSTOM |
---|
62 | void* custom; |
---|
63 | #endif |
---|
64 | #ifdef OM_TRACK_FILE_LINE |
---|
65 | #define OM_TRACK_ADDR_MEM_3 free_line |
---|
66 | |
---|
67 | /* track > 3 */ |
---|
68 | short free_line; |
---|
69 | const char* free_file; |
---|
70 | #endif |
---|
71 | #ifdef OM_TRACK_RETURN |
---|
72 | #ifndef OM_TRACK_ADDR_MEM_3 |
---|
73 | #define OM_TRACK_ADDR_MEM_3 free_r |
---|
74 | #endif |
---|
75 | const void* free_r; |
---|
76 | #endif |
---|
77 | #ifdef OM_TRACK_BACKTRACE |
---|
78 | #define OM_TRACK_ADDR_MEM_4 free_frames |
---|
79 | |
---|
80 | /* track > 4 */ |
---|
81 | void* free_frames[OM_MAX_KEPT_FRAMES]; |
---|
82 | #endif |
---|
83 | }; |
---|
84 | |
---|
85 | static omError_t omDoCheckTrackAddr(omTrackAddr d_addr, void* addr, void* bin_size, omTrackFlags_t flags, char level, |
---|
86 | omError_t report_error, OM_FLR_DECL); |
---|
87 | static int omCheckFlags(omTrackFlags_t flag); |
---|
88 | static int omCheckPattern(char* s, char p, size_t size); |
---|
89 | |
---|
90 | #define OM_TRACK_MAX 5 |
---|
91 | static struct omTrackAddr_s track_addr; /* this is only needed to determine OM_SIZEOF_TRACK_ADDR(i) */ |
---|
92 | #if 0 |
---|
93 | #define OM_SIZEOF_TRACK_ADDR_1 OM_STRICT_ALIGN_SIZE(((char*)&track_addr.alloc_frames-(char*)&track_addr)) |
---|
94 | #define OM_SIZEOF_TRACK_ADDR_2 OM_STRICT_ALIGN_SIZE(((char*)&track_addr.bin_size-(char*)&track_addr)) |
---|
95 | #define OM_SIZEOF_TRACK_ADDR_3 OM_STRICT_ALIGN_SIZE(((char*)&track_addr.free_line-(char*)&track_addr)+OM_MIN_SIZEOF_FRONT_PATTERN) |
---|
96 | #define OM_SIZEOF_TRACK_ADDR_4 OM_STRICT_ALIGN_SIZE(((char*)&track_addr.free_frames-(char*)&track_addr)+OM_MIN_SIZEOF_FRONT_PATTERN) |
---|
97 | #define OM_SIZEOF_TRACK_ADDR_5 OM_STRICT_ALIGN_SIZE(sizeof(struct omTrackAddr_s)+OM_MIN_SIZEOF_FRONT_PATTERN) |
---|
98 | #endif |
---|
99 | |
---|
100 | #define OM_SIZEOF_TRACK_ADDR_1 OM_STRICT_ALIGN_SIZE(((char*)&track_addr.OM_TRACK_ADDR_MEM_1-(char*)&track_addr)) |
---|
101 | #define OM_SIZEOF_TRACK_ADDR_2 OM_STRICT_ALIGN_SIZE(((char*)&track_addr.OM_TRACK_ADDR_MEM_2-(char*)&track_addr)) |
---|
102 | #define OM_SIZEOF_TRACK_ADDR_3 OM_STRICT_ALIGN_SIZE(((char*)&track_addr.OM_TRACK_ADDR_MEM_3-(char*)&track_addr)+OM_MIN_SIZEOF_FRONT_PATTERN) |
---|
103 | #ifdef OM_TRACK_ADDR_MEM_4 |
---|
104 | #define OM_SIZEOF_TRACK_ADDR_4 OM_STRICT_ALIGN_SIZE(((char*)&track_addr.OM_TRACK_ADDR_MEM_4-(char*)&track_addr)+OM_MIN_SIZEOF_FRONT_PATTERN) |
---|
105 | #else |
---|
106 | #define OM_SIZEOF_TRACK_ADDR_4 OM_SIZEOF_TRACK_ADDR_5 |
---|
107 | #endif |
---|
108 | #define OM_SIZEOF_TRACK_ADDR_5 OM_STRICT_ALIGN_SIZE(sizeof(struct omTrackAddr_s)+OM_MIN_SIZEOF_FRONT_PATTERN) |
---|
109 | |
---|
110 | #define OM_SIZEOF_TRACK_ADDR(i) \ |
---|
111 | (i > 3 ? \ |
---|
112 | (i == 4 ? OM_SIZEOF_TRACK_ADDR_4 : OM_SIZEOF_TRACK_ADDR_5) : \ |
---|
113 | (i == 3 ? OM_SIZEOF_TRACK_ADDR_3 : (i == 2 ? OM_SIZEOF_TRACK_ADDR_2 : OM_SIZEOF_TRACK_ADDR_1))) |
---|
114 | |
---|
115 | OM_INLINE_LOCAL omTrackAddr omOutAddr_2_TrackAddr(void* addr); |
---|
116 | |
---|
117 | #define _omOutSize_2_TrackAddrSize(size, track) \ |
---|
118 | (size + OM_SIZEOF_TRACK_ADDR(track) + (track > 2 ? OM_MIN_SIZEOF_BACK_PATTERN : 0)) |
---|
119 | |
---|
120 | #define _omTrackAddr_2_SizeOfTrackAddrHeader(d_addr) ((size_t) OM_SIZEOF_TRACK_ADDR(((omTrackAddr) (d_addr))->track)) |
---|
121 | #define _omTrackAddr_2_OutSize(d_addr) \ |
---|
122 | (((omTrackAddr) (d_addr))->track > 2 ? \ |
---|
123 | omTrack3Addr_2_OutSize(d_addr) : omSizeOfBinAddr(d_addr) - omTrackAddr_2_SizeOfTrackAddrHeader(d_addr)) |
---|
124 | #define _omTrack3Addr_2_OutSize(d_addr) \ |
---|
125 | ((((omTrackAddr) (d_addr))->flags & OM_FBIN) ? \ |
---|
126 | (((omBin)((omTrackAddr) (d_addr))->bin_size)->sizeW) << LOG_SIZEOF_LONG : \ |
---|
127 | ((size_t)((omTrackAddr) (d_addr))->bin_size)) |
---|
128 | |
---|
129 | /* assume track > 2 */ |
---|
130 | #define _omTrackAddr_2_FrontPattern(d_addr) \ |
---|
131 | ((void*)((unsigned long)d_addr + omTrackAddr_2_SizeOfTrackAddrHeader(d_addr) - OM_MIN_SIZEOF_FRONT_PATTERN)) |
---|
132 | #define _omTrackAddr_2_SizeOfFrontPattern(d_addr) \ |
---|
133 | ((char*) omTrackAddr_2_OutAddr(d_addr) - (char*) omTrackAddr_2_FrontPattern(d_addr)) |
---|
134 | #define _omTrackAddr_2_BackPattern(d_addr) \ |
---|
135 | ((char*) ((unsigned long)d_addr + omTrackAddr_2_SizeOfTrackAddrHeader(d_addr) + _omTrack3Addr_2_OutSize(d_addr))) |
---|
136 | #define _omTrackAddr_2_SizeOfBackPattern(d_addr) \ |
---|
137 | ((char*) d_addr + omSizeOfBinAddr(d_addr) - omTrackAddr_2_BackPattern(d_addr)) |
---|
138 | #define omTrackAddr_2_OutAddr(d_addr) ((void*)((unsigned long)d_addr + omTrackAddr_2_SizeOfTrackAddrHeader(d_addr))) |
---|
139 | |
---|
140 | |
---|
141 | #ifdef OM_INTERNAL_DEBUG |
---|
142 | static size_t omTrackAddr_2_SizeOfTrackAddrHeader(omTrackAddr d_addr) |
---|
143 | { |
---|
144 | size_t size; |
---|
145 | omAssume(omIsTrackAddr(d_addr) && omOutAddr_2_TrackAddr(d_addr) == d_addr && |
---|
146 | d_addr->track > 0 && d_addr->track <= 5); |
---|
147 | size = _omTrackAddr_2_SizeOfTrackAddrHeader(d_addr); |
---|
148 | return size; |
---|
149 | } |
---|
150 | static void* omTrackAddr_2_FrontPattern(omTrackAddr d_addr) |
---|
151 | { |
---|
152 | void* addr; |
---|
153 | omAssume(omIsTrackAddr(d_addr) && omOutAddr_2_TrackAddr(d_addr) == d_addr && |
---|
154 | d_addr->track > 2 && d_addr->track <= 5); |
---|
155 | addr = _omTrackAddr_2_FrontPattern(d_addr); |
---|
156 | return addr; |
---|
157 | } |
---|
158 | static size_t omTrackAddr_2_SizeOfFrontPattern(omTrackAddr d_addr) |
---|
159 | { |
---|
160 | size_t size; |
---|
161 | omAssume(omIsTrackAddr(d_addr) && omOutAddr_2_TrackAddr(d_addr) == d_addr && |
---|
162 | d_addr->track > 2 && d_addr->track <= 5); |
---|
163 | omAssume((unsigned long) omTrackAddr_2_OutAddr(d_addr) > (unsigned long) omTrackAddr_2_FrontPattern(d_addr)); |
---|
164 | size = _omTrackAddr_2_SizeOfFrontPattern(d_addr); |
---|
165 | omAssume(size > 0); |
---|
166 | return size; |
---|
167 | } |
---|
168 | static char* omTrackAddr_2_BackPattern(omTrackAddr d_addr) |
---|
169 | { |
---|
170 | char* addr; |
---|
171 | omAssume(omIsTrackAddr(d_addr) && omOutAddr_2_TrackAddr(d_addr) == d_addr && |
---|
172 | d_addr->track > 2 && d_addr->track <= 5); |
---|
173 | addr = _omTrackAddr_2_BackPattern(d_addr); |
---|
174 | omAssume(OM_ALIGN_SIZE((unsigned long) addr) == (unsigned long) addr); |
---|
175 | return addr; |
---|
176 | } |
---|
177 | static size_t omTrackAddr_2_SizeOfBackPattern(omTrackAddr d_addr) |
---|
178 | { |
---|
179 | size_t size; |
---|
180 | omAssume(omIsTrackAddr(d_addr) && omOutAddr_2_TrackAddr(d_addr) == d_addr && |
---|
181 | d_addr->track > 2 && d_addr->track <= 5); |
---|
182 | size = _omTrackAddr_2_SizeOfBackPattern(d_addr); |
---|
183 | omAssume(size > 0 && OM_ALIGN_SIZE(size) == size); |
---|
184 | return size; |
---|
185 | } |
---|
186 | static size_t omTrack3Addr_2_OutSize(omTrackAddr d_addr) |
---|
187 | { |
---|
188 | size_t size; |
---|
189 | omAssume(omIsTrackAddr(d_addr) && omOutAddr_2_TrackAddr(d_addr) == d_addr && |
---|
190 | d_addr->track > 2 && d_addr->track <= 5); |
---|
191 | omAssume(d_addr->flags > 0 && d_addr->flags < OM_FMAX && |
---|
192 | ! ((d_addr->flags & OM_FBIN) && (d_addr->flags & OM_FSIZE))); |
---|
193 | |
---|
194 | size = _omTrack3Addr_2_OutSize(d_addr); |
---|
195 | return size; |
---|
196 | } |
---|
197 | static size_t omTrackAddr_2_OutSize(omTrackAddr d_addr) |
---|
198 | { |
---|
199 | size_t size; |
---|
200 | omAssume(omIsTrackAddr(d_addr) && omOutAddr_2_TrackAddr(d_addr) == d_addr && |
---|
201 | d_addr->track > 0 && d_addr->track <= 5); |
---|
202 | |
---|
203 | size = _omTrackAddr_2_OutSize(d_addr); |
---|
204 | return size; |
---|
205 | } |
---|
206 | static size_t omOutSize_2_TrackAddrSize(size_t size, char track) |
---|
207 | { |
---|
208 | size_t da_size; |
---|
209 | omAssume(track > 0 && track <= 5); |
---|
210 | da_size = _omOutSize_2_TrackAddrSize(size, track); |
---|
211 | return da_size; |
---|
212 | } |
---|
213 | #else |
---|
214 | #define omTrackAddr_2_SizeOfTrackAddrHeader _omTrackAddr_2_SizeOfTrackAddrHeader |
---|
215 | #define omTrackAddr_2_FrontPattern _omTrackAddr_2_FrontPattern |
---|
216 | #define omTrackAddr_2_BackPattern _omTrackAddr_2_BackPattern |
---|
217 | #define omTrack3Addr_2_OutSize _omTrack3Addr_2_OutSize |
---|
218 | #define omTrackAddr_2_OutSize _omTrackAddr_2_OutSize |
---|
219 | #define omOutSize_2_TrackAddrSize _omOutSize_2_TrackAddrSize |
---|
220 | #define omTrackAddr_2_SizeOfFrontPattern _omTrackAddr_2_SizeOfFrontPattern |
---|
221 | #define omTrackAddr_2_SizeOfBackPattern _omTrackAddr_2_SizeOfBackPattern |
---|
222 | #endif |
---|
223 | |
---|
224 | OM_INLINE_LOCAL omTrackAddr omOutAddr_2_TrackAddr(void* addr) |
---|
225 | { |
---|
226 | omTrackAddr d_addr; |
---|
227 | char* page = omGetPageOfAddr(addr); |
---|
228 | size_t size = omGetTopBinOfPage((omBinPage) page)->sizeW << LOG_SIZEOF_LONG; |
---|
229 | |
---|
230 | omAssume(omIsBinPageAddr(addr)); |
---|
231 | |
---|
232 | page += SIZEOF_OM_BIN_PAGE_HEADER; |
---|
233 | d_addr = (omTrackAddr) ((unsigned long) page + (unsigned long) ((((unsigned long)addr - (unsigned long)page) / size)*size)); |
---|
234 | return d_addr; |
---|
235 | } |
---|
236 | |
---|
237 | size_t omOutSizeOfTrackAddr(void* addr) |
---|
238 | { |
---|
239 | omTrackAddr d_addr = omOutAddr_2_TrackAddr(addr); |
---|
240 | omAssume(omIsTrackAddr(addr)); |
---|
241 | return omTrackAddr_2_OutSize(d_addr); |
---|
242 | } |
---|
243 | |
---|
244 | void* omAddr_2_OutAddr(void* addr) |
---|
245 | { |
---|
246 | if (omIsTrackAddr(addr)) |
---|
247 | { |
---|
248 | return omTrackAddr_2_OutAddr(omOutAddr_2_TrackAddr(addr)); |
---|
249 | } |
---|
250 | else |
---|
251 | { |
---|
252 | return addr; |
---|
253 | } |
---|
254 | } |
---|
255 | |
---|
256 | /******************************************************************* |
---|
257 | * |
---|
258 | * Low level allocation/free routines: do the actual work, |
---|
259 | * no checks/tests, assume that everything in |
---|
260 | * environment is ok |
---|
261 | * |
---|
262 | *******************************************************************/ |
---|
263 | |
---|
264 | static omTrackAddr _omAllocTrackAddr(size_t d_size) |
---|
265 | { |
---|
266 | omTrackAddr d_addr; |
---|
267 | omBin bin; |
---|
268 | |
---|
269 | if (d_size <= OM_MAX_BLOCK_SIZE) |
---|
270 | bin = omSmallSize2TrackBin(d_size); |
---|
271 | else |
---|
272 | bin = omGetSpecTrackBin(d_size); |
---|
273 | |
---|
274 | __omTypeAllocBin(omTrackAddr, d_addr, bin); |
---|
275 | |
---|
276 | omAssume(bin->current_page == omGetPageOfAddr(d_addr)); |
---|
277 | |
---|
278 | omSetTrackOfUsedBlocks(bin->current_page->used_blocks); |
---|
279 | |
---|
280 | return d_addr; |
---|
281 | } |
---|
282 | void* omAllocTrackAddr(void* bin_size, |
---|
283 | omTrackFlags_t flags, char track, OM_FLR_DECL) |
---|
284 | { |
---|
285 | void* o_addr; |
---|
286 | size_t o_size = (flags & OM_FBIN ? ((omBin)bin_size)->sizeW << LOG_SIZEOF_LONG : |
---|
287 | (bin_size != NULL ? OM_ALIGN_SIZE((size_t) bin_size) : OM_ALIGN_SIZE(1))); |
---|
288 | omTrackAddr d_addr; |
---|
289 | size_t d_size; |
---|
290 | if (track <= 0) track = 1; |
---|
291 | if (track > 5) track = 5; |
---|
292 | |
---|
293 | if ((flags & OM_FBIN) && !omIsStaticNormalBin((omBin)bin_size)) |
---|
294 | /* Need to set track >= 3 such that bin_size is kept: Needed |
---|
295 | for om_KeptAddr */ |
---|
296 | track = (track > 3 ? track : 3); |
---|
297 | d_size = omOutSize_2_TrackAddrSize(o_size, track); |
---|
298 | |
---|
299 | d_addr = _omAllocTrackAddr(d_size); |
---|
300 | d_addr->next = (void*)-1; |
---|
301 | d_addr->track = track; |
---|
302 | d_addr->flags = flags | OM_FUSED; |
---|
303 | if (om_Opts.MarkAsStatic) |
---|
304 | d_addr->flags |= OM_FSTATIC; |
---|
305 | |
---|
306 | #ifdef OM_TRACK_FILE_LINE |
---|
307 | d_addr->alloc_file = f; |
---|
308 | d_addr->alloc_line = (l > SHRT_MAX || l < 0 ? 0 : l); |
---|
309 | #endif |
---|
310 | #ifdef OM_TRACK_RETURN |
---|
311 | d_addr->alloc_r = r; |
---|
312 | #endif |
---|
313 | |
---|
314 | o_addr = omTrackAddr_2_OutAddr(d_addr); |
---|
315 | if (track > 1) |
---|
316 | { |
---|
317 | #ifdef OM_INTERNAL_DEBUG |
---|
318 | #define FROM_FRAMES 0 |
---|
319 | #else |
---|
320 | #define FROM_FRAMES 2 |
---|
321 | #endif |
---|
322 | |
---|
323 | #ifdef OM_TRACK_BACKTRACE |
---|
324 | omGetBackTrace((void **)d_addr->alloc_frames, FROM_FRAMES, OM_MAX_KEPT_FRAMES); |
---|
325 | #endif |
---|
326 | |
---|
327 | if (track > 2) |
---|
328 | { |
---|
329 | if (flags & OM_FBIN && ((omBin) bin_size)->sticky) |
---|
330 | { |
---|
331 | d_addr->bin_size = (void*)(((omBin) bin_size)->sizeW<<LOG_SIZEOF_LONG); |
---|
332 | d_addr->flags &= ~OM_FBIN; |
---|
333 | d_addr->flags |= OM_FSIZE; |
---|
334 | } |
---|
335 | else |
---|
336 | d_addr->bin_size = (flags & OM_FBIN ? bin_size : (void*) o_size); |
---|
337 | omAssume(OM_ALIGN_SIZE((size_t)d_addr->bin_size) == (size_t) d_addr->bin_size); |
---|
338 | |
---|
339 | memset(omTrackAddr_2_FrontPattern(d_addr), OM_FRONT_PATTERN, omTrackAddr_2_SizeOfFrontPattern(d_addr)); |
---|
340 | if (! (flags & OM_FZERO)) memset(o_addr, OM_INIT_PATTERN, o_size); |
---|
341 | memset(omTrackAddr_2_BackPattern(d_addr), OM_BACK_PATTERN, omTrackAddr_2_SizeOfBackPattern(d_addr)); |
---|
342 | |
---|
343 | #ifdef OM_TRACK_CUSTOM |
---|
344 | d_addr->custom = NULL; |
---|
345 | #endif |
---|
346 | if (track > 3) |
---|
347 | { |
---|
348 | #ifdef OM_TRACK_FILE_LINE |
---|
349 | d_addr->free_line = -1; |
---|
350 | d_addr->free_file = (char*) -1; |
---|
351 | #endif |
---|
352 | #ifdef OM_TRACK_RETURN |
---|
353 | d_addr->free_r = (void*) -1; |
---|
354 | #endif |
---|
355 | |
---|
356 | #ifdef OM_TRACK_BACKTRACE |
---|
357 | if (track > 4) |
---|
358 | memset(&d_addr->free_frames, 0, OM_MAX_KEPT_FRAMES*SIZEOF_VOIDP); |
---|
359 | #endif |
---|
360 | } |
---|
361 | } |
---|
362 | } |
---|
363 | if (flags & OM_FZERO) omMemsetW(o_addr, 0, o_size >> LOG_SIZEOF_LONG); |
---|
364 | return o_addr; |
---|
365 | } |
---|
366 | |
---|
367 | |
---|
368 | void* omMarkAsFreeTrackAddr(void* addr, int keep, omTrackFlags_t *flags, OM_FLR_DECL) |
---|
369 | { |
---|
370 | omTrackAddr d_addr = omOutAddr_2_TrackAddr(addr); |
---|
371 | omAssume(omIsTrackAddr(addr)); |
---|
372 | |
---|
373 | d_addr->next = (void*) -1; |
---|
374 | if (d_addr->track > 2) |
---|
375 | { |
---|
376 | if (d_addr->flags & OM_FUSED) |
---|
377 | { |
---|
378 | memset(omTrackAddr_2_OutAddr(d_addr), OM_FREE_PATTERN, omTrackAddr_2_OutSize(d_addr)); |
---|
379 | if (d_addr->track > 3) |
---|
380 | { |
---|
381 | #ifdef OM_TRACK_FILE_LINE |
---|
382 | d_addr->free_line = l; |
---|
383 | d_addr->free_file = f; |
---|
384 | #endif |
---|
385 | #ifdef OM_TRACK_RETURN |
---|
386 | d_addr->free_r = r; |
---|
387 | #endif |
---|
388 | |
---|
389 | #ifdef OM_TRACK_BACKTRACE |
---|
390 | if (d_addr->track > 4) |
---|
391 | omGetBackTrace(d_addr->free_frames, FROM_FRAMES, OM_MAX_KEPT_FRAMES); |
---|
392 | #endif |
---|
393 | } |
---|
394 | } |
---|
395 | else |
---|
396 | { |
---|
397 | omAssume(d_addr->flags & OM_FKEPT); |
---|
398 | } |
---|
399 | } |
---|
400 | if (d_addr->flags & OM_FKEEP) *flags |= OM_FKEEP; |
---|
401 | d_addr->flags &= ~OM_FUSED; |
---|
402 | if (keep) d_addr->flags |= OM_FKEPT; |
---|
403 | else d_addr->flags &= ~OM_FKEPT; |
---|
404 | |
---|
405 | return(void*) d_addr; |
---|
406 | } |
---|
407 | |
---|
408 | void omFreeTrackAddr(void* d_addr) |
---|
409 | { |
---|
410 | omBinPage page; |
---|
411 | omBin bin; |
---|
412 | |
---|
413 | omAssume(omIsBinPageAddr(d_addr)); |
---|
414 | omAssume(d_addr != NULL && omIsTrackAddr(d_addr)); |
---|
415 | d_addr = omOutAddr_2_TrackAddr(d_addr); |
---|
416 | |
---|
417 | page = omGetBinPageOfAddr((void*) d_addr); |
---|
418 | bin = omGetTopBinOfPage(page); |
---|
419 | /* Ok, here is how it works: |
---|
420 | 1. we unset the first bit of used_blocks |
---|
421 | ==> used_blocks >= 0 |
---|
422 | 2. we do a normal free |
---|
423 | 3. if page of addr was freed, then om_JustFreedPage |
---|
424 | is != NULL ==> nothing to be done by us |
---|
425 | else |
---|
426 | page is still active ==> reset first bit of used_blocks |
---|
427 | */ |
---|
428 | |
---|
429 | omUnsetTrackOfUsedBlocks(page->used_blocks); |
---|
430 | |
---|
431 | om_JustFreedPage = NULL; |
---|
432 | |
---|
433 | __omFreeBinAddr(d_addr); |
---|
434 | |
---|
435 | if (page != om_JustFreedPage) |
---|
436 | omSetTrackOfUsedBlocks(page->used_blocks); |
---|
437 | else |
---|
438 | { |
---|
439 | /* Still need to check wheter we need to get rid of SpecBin */ |
---|
440 | if (bin->last_page == NULL && ! omIsStaticTrackBin(bin)) |
---|
441 | omDeleteSpecBin(&bin); |
---|
442 | } |
---|
443 | } |
---|
444 | |
---|
445 | /******************************************************************* |
---|
446 | * |
---|
447 | * Checking a Track Addr |
---|
448 | * |
---|
449 | * |
---|
450 | *******************************************************************/ |
---|
451 | |
---|
452 | omError_t omCheckTrackAddr(void* addr, void* bin_size, omTrackFlags_t flags, char level, |
---|
453 | omError_t report, OM_FLR_DECL) |
---|
454 | { |
---|
455 | omTrackAddr d_addr = omOutAddr_2_TrackAddr(addr); |
---|
456 | omAssume(omIsTrackAddr(addr)); |
---|
457 | omAssume(! omCheckPtr(addr, 0, OM_FLR)); |
---|
458 | |
---|
459 | omAddrCheckReturnCorrupted(d_addr->track < 1 || d_addr->track > OM_TRACK_MAX); |
---|
460 | omAddrCheckReturnError((flags & OM_FUSED) && omTrackAddr_2_OutAddr(d_addr) != addr, omError_FalseAddrOrMemoryCorrupted); |
---|
461 | |
---|
462 | omCheckReturn(omDoCheckBinAddr(d_addr, 0, (flags & OM_FUSED ? OM_FUSED : (flags & OM_FKEPT ? OM_FKEPT: 0)), |
---|
463 | level, report, OM_FLR_VAL)); |
---|
464 | return omDoCheckTrackAddr(d_addr, addr, bin_size, flags, level, report, OM_FLR_VAL); |
---|
465 | } |
---|
466 | |
---|
467 | |
---|
468 | static omError_t omDoCheckTrackAddr(omTrackAddr d_addr, void* addr, void* bin_size, omTrackFlags_t flags, char level, |
---|
469 | omError_t report, OM_FLR_DECL) |
---|
470 | { |
---|
471 | if (flags & OM_FUSED) |
---|
472 | omAddrCheckReturnError(d_addr->next != ((void*) -1), omError_FreedAddrOrMemoryCorrupted); |
---|
473 | else |
---|
474 | omAddrCheckReturnError(d_addr->next != NULL && omCheckPtr(d_addr->next, omError_MaxError, OM_FLR_VAL), |
---|
475 | omError_FreedAddrOrMemoryCorrupted); |
---|
476 | omAddrCheckReturnCorrupted(omCheckFlags(d_addr->flags)); |
---|
477 | |
---|
478 | omAddrCheckReturnError(level > 1 && (flags & OM_FUSED) && omIsInKeptAddrList(d_addr), omError_FreedAddr); |
---|
479 | omAddrCheckReturnError((d_addr->flags & OM_FUSED) ^ (flags & OM_FUSED), omError_FreedAddrOrMemoryCorrupted); |
---|
480 | |
---|
481 | if (flags & OM_FBINADDR && flags & OM_FSIZE) |
---|
482 | omAddrCheckReturnError(omTrackAddr_2_OutSize(d_addr) != (size_t) bin_size, omError_WrongSize); |
---|
483 | |
---|
484 | if (d_addr->track > 2) |
---|
485 | { |
---|
486 | if (d_addr->flags & OM_FBIN) |
---|
487 | { |
---|
488 | omAddrCheckReturnCorrupted(!omIsKnownTopBin((omBin) d_addr->bin_size, 1)); |
---|
489 | } |
---|
490 | else |
---|
491 | { |
---|
492 | omAssume(d_addr->flags & OM_FSIZE); |
---|
493 | |
---|
494 | omAddrCheckReturnCorrupted(!OM_IS_ALIGNED(d_addr->bin_size)); |
---|
495 | omAddrCheckReturnCorrupted((size_t) d_addr->bin_size > |
---|
496 | omSizeOfBinAddr(d_addr) |
---|
497 | - omTrackAddr_2_SizeOfTrackAddrHeader(d_addr) |
---|
498 | - OM_MIN_SIZEOF_BACK_PATTERN); |
---|
499 | /* Hmm .. here I'd love to have a stricter bound */ |
---|
500 | omAddrCheckReturnCorrupted((size_t) d_addr->bin_size < SIZEOF_OM_ALIGNMENT); |
---|
501 | } |
---|
502 | |
---|
503 | omAddrCheckReturnError((flags & OM_FBINADDR) && !((d_addr->flags & OM_FBIN) || ((size_t) d_addr->bin_size <= OM_MAX_BLOCK_SIZE)), omError_NotBinAddr); |
---|
504 | |
---|
505 | if (flags & OM_FBIN) |
---|
506 | { |
---|
507 | if (d_addr->flags & OM_FBIN) |
---|
508 | omAddrCheckReturnError(((omBin) d_addr->bin_size)->sizeW != ((omBin) bin_size)->sizeW, omError_WrongBin); |
---|
509 | else |
---|
510 | omAddrCheckReturnError((((omBin) bin_size)->sizeW << LOG_SIZEOF_LONG) != OM_ALIGN_SIZE((size_t) d_addr->bin_size), omError_WrongBin); |
---|
511 | } |
---|
512 | else if (flags & OM_FSIZE) |
---|
513 | { |
---|
514 | if (d_addr->flags & OM_FBIN) |
---|
515 | { |
---|
516 | omAddrCheckReturnError((((omBin) d_addr->bin_size)->sizeW << LOG_SIZEOF_LONG) < ((size_t) bin_size), omError_WrongSize); |
---|
517 | } |
---|
518 | else |
---|
519 | { |
---|
520 | omAddrCheckReturnError((size_t) d_addr->bin_size < (size_t) bin_size, omError_WrongSize); |
---|
521 | } |
---|
522 | } |
---|
523 | |
---|
524 | omAddrCheckReturnError(omCheckPattern(omTrackAddr_2_FrontPattern(d_addr), OM_FRONT_PATTERN,omTrackAddr_2_SizeOfFrontPattern(d_addr)),omError_FrontPattern); |
---|
525 | omAddrCheckReturnError(omCheckPattern(omTrackAddr_2_BackPattern(d_addr), OM_BACK_PATTERN,omTrackAddr_2_SizeOfBackPattern(d_addr)),omError_BackPattern); |
---|
526 | if (! (d_addr->flags & OM_FUSED)) |
---|
527 | omAddrCheckReturnError(omCheckPattern(omTrackAddr_2_OutAddr(addr), OM_FREE_PATTERN, omTrackAddr_2_OutSize(d_addr)),omError_FreePattern); |
---|
528 | |
---|
529 | if (d_addr->track > 3) |
---|
530 | { |
---|
531 | #ifdef OM_TRACK_FILE_LINE |
---|
532 | if (d_addr->flags & OM_FUSED) |
---|
533 | { |
---|
534 | omAddrCheckReturnCorrupted(d_addr->free_line != -1); |
---|
535 | omAddrCheckReturnCorrupted(d_addr->free_file != (void*) -1); |
---|
536 | } |
---|
537 | else |
---|
538 | { |
---|
539 | omAddrCheckReturnCorrupted(d_addr->free_line < 0); |
---|
540 | omAddrCheckReturnCorrupted(d_addr->free_file == (void*) -1); |
---|
541 | } |
---|
542 | #endif |
---|
543 | #ifdef OM_TRACK_RETURN |
---|
544 | omAddrCheckReturnCorrupted((d_addr->flags & OM_FUSED) |
---|
545 | && (d_addr->free_r != (void*) -1)); |
---|
546 | #endif |
---|
547 | } |
---|
548 | } |
---|
549 | else |
---|
550 | { |
---|
551 | /* track < 2 */ |
---|
552 | if (flags & OM_FBIN) |
---|
553 | { |
---|
554 | size_t size = omTrackAddr_2_OutSize(d_addr); |
---|
555 | omAddrCheckReturnError(!omIsKnownTopBin((omBin) bin_size, 1), omError_UnknownBin); |
---|
556 | omAddrCheckReturnError(size < (((omBin)bin_size)->sizeW<<LOG_SIZEOF_LONG), omError_WrongBin); |
---|
557 | } |
---|
558 | else if (flags & OM_FSIZE |
---|
559 | && (!(flags & OM_FSLOPPY) |
---|
560 | || (size_t)bin_size > 0)) |
---|
561 | { |
---|
562 | omAddrCheckReturnError(omTrackAddr_2_OutSize(d_addr) < (size_t) bin_size, omError_WrongSize); |
---|
563 | } |
---|
564 | else if (flags & OM_FBINADDR) |
---|
565 | { |
---|
566 | size_t size = omTrackAddr_2_OutSize(d_addr); |
---|
567 | omAddrCheckReturnError(size > OM_MAX_BLOCK_SIZE, omError_NotBinAddr); |
---|
568 | } |
---|
569 | } |
---|
570 | return omError_NoError; |
---|
571 | } |
---|
572 | |
---|
573 | static int omCheckFlags(omTrackFlags_t flag) |
---|
574 | { |
---|
575 | if (flag > OM_FMAX) return 1; |
---|
576 | if (! ((flag & OM_FBIN) ^ (flag & OM_FSIZE))) return 1; |
---|
577 | if (flag & OM_FUSED && flag & OM_FKEPT) return 1; |
---|
578 | return 0; |
---|
579 | } |
---|
580 | |
---|
581 | static int omCheckPattern(char* s, char p, size_t size) |
---|
582 | { |
---|
583 | int i; |
---|
584 | for (i=0; i<size; i++) |
---|
585 | { |
---|
586 | if (s[i] != p) |
---|
587 | return 1; |
---|
588 | } |
---|
589 | return 0; |
---|
590 | } |
---|
591 | |
---|
592 | #ifdef OM_TRACK_BACKTRACE |
---|
593 | #define OM_ALLOC_FRAMES(d_addr) d_addr->alloc_frames |
---|
594 | #define OM_FREE_FRAMES(d_addr) d_addr->free_frames |
---|
595 | #else |
---|
596 | #define OM_ALLOC_FRAMES(d) NULL |
---|
597 | #define OM_FREE_FRAMES(d) NULL |
---|
598 | #endif |
---|
599 | |
---|
600 | void omPrintTrackAddrInfo(FILE* fd, void* addr, int max_frames) |
---|
601 | { |
---|
602 | omTrackAddr d_addr = omOutAddr_2_TrackAddr(addr); |
---|
603 | omAssume(d_addr->track > 0); |
---|
604 | if (max_frames <= 0) return; |
---|
605 | |
---|
606 | if (max_frames > OM_MAX_KEPT_FRAMES) max_frames = OM_MAX_KEPT_FRAMES; |
---|
607 | |
---|
608 | fprintf(fd, " allocated at "); |
---|
609 | if (! _omPrintBackTrace((void **)OM_ALLOC_FRAMES(d_addr), |
---|
610 | (d_addr->track > 1 ? max_frames : 0), |
---|
611 | fd, |
---|
612 | OM_FLR_ARG(d_addr->alloc_file, d_addr->alloc_line, d_addr->alloc_r))) |
---|
613 | fprintf(fd," ??"); |
---|
614 | if (d_addr->track > 1) |
---|
615 | { |
---|
616 | if (d_addr->track > 3 && ! (d_addr->flags & OM_FUSED)) |
---|
617 | { |
---|
618 | fprintf(fd, "\n freed at "); |
---|
619 | if (! _omPrintBackTrace(OM_FREE_FRAMES(d_addr), |
---|
620 | (d_addr->track > 4 ? max_frames : 0), |
---|
621 | fd, |
---|
622 | OM_FLR_ARG(d_addr->free_file, d_addr->free_line, d_addr->free_r))) |
---|
623 | fprintf(fd," ??"); |
---|
624 | } |
---|
625 | } |
---|
626 | fprintf(fd, "\n"); |
---|
627 | fflush(fd); |
---|
628 | } |
---|
629 | |
---|
630 | /******************************************************************* |
---|
631 | * |
---|
632 | * Misc routines for marking, etc. |
---|
633 | * |
---|
634 | *******************************************************************/ |
---|
635 | int omIsStaticTrackAddr(void* addr) |
---|
636 | { |
---|
637 | omTrackAddr d_addr = omOutAddr_2_TrackAddr(addr); |
---|
638 | omAssume(omIsTrackAddr(addr)); |
---|
639 | |
---|
640 | return (d_addr->flags & OM_FSTATIC); |
---|
641 | } |
---|
642 | |
---|
643 | omBin omGetOrigSpecBinOfTrackAddr(void* addr) |
---|
644 | { |
---|
645 | omTrackAddr d_addr = omOutAddr_2_TrackAddr(addr); |
---|
646 | omAssume(omIsTrackAddr(addr)); |
---|
647 | |
---|
648 | if (d_addr->track > 2 && (d_addr->flags & OM_FBIN)) |
---|
649 | { |
---|
650 | omBin bin = (omBin) d_addr->bin_size; |
---|
651 | if (omIsSpecBin(bin)) return bin; |
---|
652 | } |
---|
653 | return NULL; |
---|
654 | } |
---|
655 | |
---|
656 | void omMarkAsStaticAddr(void* addr) |
---|
657 | { |
---|
658 | if (omIsTrackAddr(addr)) |
---|
659 | { |
---|
660 | omTrackAddr d_addr = omOutAddr_2_TrackAddr(addr); |
---|
661 | d_addr->flags |= OM_FSTATIC; |
---|
662 | } |
---|
663 | } |
---|
664 | |
---|
665 | void omUnMarkAsStaticAddr(void* addr) |
---|
666 | { |
---|
667 | if (omIsTrackAddr(addr)) |
---|
668 | { |
---|
669 | omTrackAddr d_addr = omOutAddr_2_TrackAddr(addr); |
---|
670 | d_addr->flags &= ~OM_FSTATIC; |
---|
671 | } |
---|
672 | } |
---|
673 | |
---|
674 | static void _omMarkAsStatic(void* addr) |
---|
675 | { |
---|
676 | omTrackAddr d_addr = (omTrackAddr) addr; |
---|
677 | if (!omCheckPtr(addr, omError_MaxError, OM_FLR)) |
---|
678 | { |
---|
679 | omAssume(omIsTrackAddr(addr) && omOutAddr_2_TrackAddr(addr) == d_addr); |
---|
680 | d_addr->flags |= OM_FSTATIC; |
---|
681 | } |
---|
682 | } |
---|
683 | |
---|
684 | static void _omUnMarkAsStatic(void* addr) |
---|
685 | { |
---|
686 | omTrackAddr d_addr = (omTrackAddr) addr; |
---|
687 | omAssume(omIsTrackAddr(addr) && omOutAddr_2_TrackAddr(addr) == d_addr); |
---|
688 | d_addr->flags &= ~OM_FSTATIC; |
---|
689 | } |
---|
690 | |
---|
691 | void omUnMarkMemoryAsStatic() |
---|
692 | { |
---|
693 | omIterateTroughAddrs(0, 1, _omUnMarkAsStatic, NULL); |
---|
694 | } |
---|
695 | |
---|
696 | void omMarkMemoryAsStatic() |
---|
697 | { |
---|
698 | omIterateTroughAddrs(0, 1, _omMarkAsStatic, NULL); |
---|
699 | } |
---|
700 | |
---|
701 | #ifdef OM_TRACK_CUSTOM |
---|
702 | void omSetCustomOfTrackAddr(void* addr, void* value) |
---|
703 | { |
---|
704 | omTrackAddr d_addr = omOutAddr_2_TrackAddr(addr); |
---|
705 | omAssume(omIsTrackAddr(addr)); |
---|
706 | |
---|
707 | if (d_addr->track > 2) |
---|
708 | { |
---|
709 | d_addr->custom = value; |
---|
710 | } |
---|
711 | } |
---|
712 | |
---|
713 | void* omGetCustomOfTrackAddr(void* addr) |
---|
714 | { |
---|
715 | omTrackAddr d_addr = omOutAddr_2_TrackAddr(addr); |
---|
716 | omAssume(omIsTrackAddr(addr)); |
---|
717 | |
---|
718 | if (d_addr->track > 2) |
---|
719 | { |
---|
720 | return d_addr->custom; |
---|
721 | } |
---|
722 | else |
---|
723 | { |
---|
724 | return NULL; |
---|
725 | } |
---|
726 | } |
---|
727 | #endif |
---|
728 | |
---|
729 | #endif /* OM_HAVE_TRACK */ |
---|
730 | |
---|
731 | #ifndef OM_NDEBUG |
---|
732 | |
---|
733 | #ifndef OM_HAVE_TRACK |
---|
734 | #include "om_Alloc.h" |
---|
735 | #endif |
---|
736 | |
---|
737 | int omIsInKeptAddrList(void* addr) |
---|
738 | { |
---|
739 | void* ptr = om_KeptAddr; |
---|
740 | int ret = 0; |
---|
741 | |
---|
742 | #ifdef OM_HAVE_TRACK |
---|
743 | if (omIsTrackAddr(addr)) |
---|
744 | addr = omOutAddr_2_TrackAddr(addr); |
---|
745 | #endif |
---|
746 | |
---|
747 | if (om_LastKeptAddr != NULL) |
---|
748 | *((void**) om_LastKeptAddr) = om_AlwaysKeptAddrs; |
---|
749 | |
---|
750 | while (ptr != NULL) |
---|
751 | { |
---|
752 | if (ptr == addr) |
---|
753 | { |
---|
754 | ret = 1; break; |
---|
755 | } |
---|
756 | ptr = *((void**) ptr); |
---|
757 | } |
---|
758 | |
---|
759 | if (om_LastKeptAddr != NULL) |
---|
760 | *((void**) om_LastKeptAddr) = NULL; |
---|
761 | |
---|
762 | return ret; |
---|
763 | } |
---|
764 | #endif /*!OM_NDEBUG*/ |
---|