1
2 /***************************************************************************
3 * __ __ _ ___________ *
4 * \ \ / /| |____ ____| *
5 * \ \ / / | | | | *
6 * \ \ /\ / / | | | | *
7 * \ \/ \/ / | | | | *
8 * \ /\ / | | | | *
9 * \/ \/ |_| |_| *
10 * *
11 * Wiimms ISO Tools *
12 * http://wit.wiimm.de/ *
13 * *
14 ***************************************************************************
15 * *
16 * This file is part of the WIT project. *
17 * Visit http://wit.wiimm.de/ for project details and sources. *
18 * *
19 * Copyright (c) 2009-2013 by Dirk Clemens <wiimm@wiimm.de> *
20 * *
21 ***************************************************************************
22 * *
23 * This program is free software; you can redistribute it and/or modify *
24 * it under the terms of the GNU General Public License as published by *
25 * the Free Software Foundation; either version 2 of the License, or *
26 * (at your option) any later version. *
27 * *
28 * This program is distributed in the hope that it will be useful, *
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
31 * GNU General Public License for more details. *
32 * *
33 * See file gpl-2.0.txt or http://www.gnu.org/licenses/gpl-2.0.txt *
34 * *
35 ***************************************************************************/
36
37 #define WIIMM_DEBUG_C 1
38 #include "debug.h"
39
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <stdarg.h>
43
44 #include "lib-std.h"
45
46 //
47 ///////////////////////////////////////////////////////////////////////////////
48 /////////////// trace functions ///////////////
49 ///////////////////////////////////////////////////////////////////////////////
50
51 FILE * TRACE_FILE = 0;
52
53 unsigned GetTimerMSec();
54
55 ///////////////////////////////////////////////////////////////////////////////
56
trace_helper(int print_stderr,ccp format,va_list arg)57 static void trace_helper ( int print_stderr, ccp format, va_list arg )
58 {
59 if (!TRACE_FILE)
60 {
61 TRACE_FILE = fopen("_trace.tmp","wb");
62 if (!TRACE_FILE)
63 TRACE_FILE = stderr;
64 }
65
66 unsigned msec = GetTimerMSec();
67
68 if ( print_stderr || TRACE_FILE == stderr )
69 {
70 fflush(stdout);
71 fprintf(stderr,"%4d.%03d ",msec/1000,msec%1000);
72 va_list arg2;
73 va_copy(arg2,arg);
74 vfprintf(stderr,format,arg2);
75 va_end(arg2);
76 fflush(stderr);
77 }
78
79 if ( TRACE_FILE != stderr )
80 {
81 fprintf(TRACE_FILE,"%4d.%03d ",msec/1000,msec%1000);
82 vfprintf(TRACE_FILE,format,arg);
83 fflush(TRACE_FILE);
84 }
85 }
86
87 ///////////////////////////////////////////////////////////////////////////////
88
89 #undef TRACE_ARG_FUNC
90
TRACE_ARG_FUNC(ccp format,va_list arg)91 void TRACE_ARG_FUNC ( ccp format, va_list arg )
92 {
93 trace_helper(0,format,arg);
94 }
95
96 ///////////////////////////////////////////////////////////////////////////////
97
98 #undef TRACE_FUNC
99
TRACE_FUNC(ccp format,...)100 void TRACE_FUNC ( ccp format, ... )
101 {
102 va_list arg;
103 va_start(arg,format);
104 trace_helper(0,format,arg);
105 va_end(arg);
106 }
107
108 ///////////////////////////////////////////////////////////////////////////////
109
110 #undef PRINT_ARG_FUNC
111
PRINT_ARG_FUNC(ccp format,va_list arg)112 void PRINT_ARG_FUNC ( ccp format, va_list arg )
113 {
114 trace_helper(1,format,arg);
115 }
116
117 ///////////////////////////////////////////////////////////////////////////////
118
119 #undef PRINT_FUNC
120
PRINT_FUNC(ccp format,...)121 void PRINT_FUNC ( ccp format, ... )
122 {
123 va_list arg;
124 va_start(arg,format);
125 trace_helper(1,format,arg);
126 va_end(arg);
127 }
128
129 ///////////////////////////////////////////////////////////////////////////////
130
131 #undef WAIT_ARG_FUNC
132
WAIT_ARG_FUNC(ccp format,va_list arg)133 void WAIT_ARG_FUNC ( ccp format, va_list arg )
134 {
135 if ( format && *format )
136 trace_helper(1,format,arg);
137 PRINT_FUNC(">>>>>> PRESS RETURN: ");
138 getchar();
139 }
140
141 ///////////////////////////////////////////////////////////////////////////////
142
143 #undef WAIT_FUNC
144
WAIT_FUNC(ccp format,...)145 void WAIT_FUNC ( ccp format, ... )
146 {
147 va_list arg;
148 va_start(arg,format);
149 WAIT_ARG_FUNC(format,arg);
150 va_end(arg);
151 }
152
153 //
154 ///////////////////////////////////////////////////////////////////////////////
155 /////////////// alloc/free system ///////////////
156 ///////////////////////////////////////////////////////////////////////////////
157
158 #if TRACE_ALLOC_MODE > 2
159 #define MEM_FILLER_SIZE 8
160 static u8 mem_filler[MEM_FILLER_SIZE];
161 #else
162 #define MEM_FILLER_SIZE 0
163 #endif
164
165 #if TRACE_ALLOC_MODE > 1
166 #define MPARAM ccp func, ccp file, uint line,
167 #define MCALL func,file,line,
168 #define PRINT_OOM(...) \
169 PrintError(func,file,line,0,ERR_OUT_OF_MEMORY,__VA_ARGS__)
170 #else
171 #define MPARAM
172 #define MCALL
173 #define PRINT_OOM(...) \
174 PrintError(__FUNCTION__,__FILE__,__LINE__,0,ERR_OUT_OF_MEMORY,__VA_ARGS__)
175 #endif
176
177 ///////////////////////////////////////////////////////////////////////////////
178
my_free(void * ptr)179 void my_free ( void * ptr )
180 {
181 free(ptr);
182 }
183
184 ///////////////////////////////////////////////////////////////////////////////
185 ///////////////////////////////////////////////////////////////////////////////
186
my_calloc(MPARAM size_t nmemb,size_t size)187 void * my_calloc ( MPARAM size_t nmemb, size_t size )
188 {
189 void * res = calloc(nmemb,size);
190 if (!res)
191 PRINT_OOM("Out of memory while calloc() %zu bytes (%zu*%zu=0x%zx)\n",
192 nmemb*size, nmemb, size, nmemb*size );
193 return res;
194 }
195
196 ///////////////////////////////////////////////////////////////////////////////
197
my_malloc(MPARAM size_t size)198 void * my_malloc ( MPARAM size_t size )
199 {
200 void * res = malloc(size);
201 if (!res)
202 PRINT_OOM("Out of memory while malloc() %zu bytes (0x%zx)\n",
203 size, size );
204 return res;
205 }
206
207 ///////////////////////////////////////////////////////////////////////////////
208
my_realloc(MPARAM void * ptr,size_t size)209 void * my_realloc ( MPARAM void * ptr, size_t size )
210 {
211 void * res = realloc(ptr,size);
212 if (!res)
213 PRINT_OOM("Out of memory while realloc() %zu bytes (0x%zx)\n",
214 size, size );
215 return res;
216 }
217
218 ///////////////////////////////////////////////////////////////////////////////
219 ///////////////////////////////////////////////////////////////////////////////
220
my_strdup(MPARAM ccp src)221 char * my_strdup ( MPARAM ccp src )
222 {
223 char * res = strdup(src);
224 if (!res)
225 {
226 const uint size = src ? strlen(src)+1 : 0;
227 PRINT_OOM("Out of memory while strdup() %u bytes (0x%x)\n",
228 size, size );
229 }
230 return res;
231 }
232
233 ///////////////////////////////////////////////////////////////////////////////
234
my_strdup2(MPARAM ccp src1,ccp src2)235 char * my_strdup2 ( MPARAM ccp src1, ccp src2 )
236 {
237 const uint len1 = src1 ? strlen(src1) : 0;
238 const uint len2 = src2 ? strlen(src2) : 0;
239 char * res = my_malloc( MCALL len1+len2+1 );
240 if (len1)
241 memcpy(res,src1,len1);
242 if (len2)
243 memcpy(res+len1,src2,len2);
244 res[len1+len2] = 0;
245 return res;
246 }
247
248 ///////////////////////////////////////////////////////////////////////////////
249
my_strdup3(MPARAM ccp src1,ccp src2,ccp src3)250 char * my_strdup3 ( MPARAM ccp src1, ccp src2, ccp src3 )
251 {
252 const uint len1 = src1 ? strlen(src1) : 0;
253 const uint len2 = src2 ? strlen(src2) : 0;
254 const uint len3 = src3 ? strlen(src3) : 0;
255 char * res = my_malloc( MCALL len1+len2+len3+1 );
256 char * dest = res;
257 if (len1)
258 {
259 memcpy(dest,src1,len1);
260 dest += len1;
261 }
262 if (len2)
263 {
264 memcpy(dest,src2,len2);
265 dest += len2;
266 }
267 if (len3)
268 {
269 memcpy(dest,src3,len3);
270 dest += len3;
271 }
272 *dest = 0;
273 return res;
274 }
275
276 ///////////////////////////////////////////////////////////////////////////////
277
my_memdup(MPARAM const void * src,size_t copylen)278 void * my_memdup ( MPARAM const void * src, size_t copylen )
279 {
280 char * dest = my_malloc( MCALL copylen+1);
281 memcpy(dest,src,copylen);
282 dest[copylen] = 0;
283 return dest;
284 }
285
286 //
287 ///////////////////////////////////////////////////////////////////////////////
288 ///////////////////////////////////////////////////////////////////////////////
289 #if TRACE_ALLOC_MODE > 2
290 ///////////////////////////////////////////////////////////////////////////////
291
292 typedef struct mem_info_t
293 {
294 ccp func;
295 ccp file;
296 uint line;
297 u8 * data;
298 uint size;
299 uint seqnum;
300
301 } mem_info_t;
302
303 //-----------------------------------------------------------------------------
304
305 static mem_info_t * mem_list = 0;
306 static uint mem_used = 0;
307 static uint mem_size = 0;
308 static FILE *mem_log = 0;
309 static uint mem_seqnum = 0;
310
311 ///////////////////////////////////////////////////////////////////////////////
312
OpenMemLog()313 static FILE * OpenMemLog()
314 {
315 static bool done = false;
316 if (!done)
317 {
318 done = true;
319 mem_log = fopen("_alloc-err-log.tmp","wb");
320 }
321 return mem_log;
322 }
323
324 ///////////////////////////////////////////////////////////////////////////////
325
MemLog(ccp func,ccp file,uint line,ccp info,u8 * ptr,bool no_stderr)326 static void MemLog
327 ( ccp func, ccp file, uint line, ccp info, u8 * ptr, bool no_stderr )
328 {
329 if (!no_stderr)
330 {
331 fprintf(stderr,"MEM-ERR[%s,%p] %s() @ %s#%u\n",
332 info, ptr, func, file, line );
333 fflush(stderr);
334 }
335
336 if (OpenMemLog())
337 {
338 fprintf(mem_log,"[%s,%p] %s() @ %s#%u\n",
339 info, ptr, func, file, line );
340 fflush(mem_log);
341 }
342 }
343
344 ///////////////////////////////////////////////////////////////////////////////
345
MemLogItem(ccp func,ccp file,uint line,ccp info,const mem_info_t * mi)346 static void MemLogItem ( ccp func, ccp file, uint line, ccp info, const mem_info_t * mi )
347 {
348 if (func)
349 fprintf(stderr,"MEM-ERR[%s] %s() @ %s#%u\n",
350 info, func, file, line );
351 fprintf(stderr,"MEM-ERR[%s,%u] %s() @ %s#%u\n",
352 info, mi->seqnum, mi->func, mi->file, mi->line );
353 fflush(stderr);
354
355 if (OpenMemLog())
356 {
357 if (func)
358 fprintf(mem_log,"[%s] %s() @ %s#%u\n",
359 info, func, file, line );
360 fprintf(mem_log,"[%s,%u] %s() @ %s#%u\n",
361 info, mi->seqnum, mi->func, mi->file, mi->line );
362 HexDump16( mem_log, 10, 0, mi->data - MEM_FILLER_SIZE, 2*MEM_FILLER_SIZE );
363 HexDump16( mem_log, 10, mi->size + MEM_FILLER_SIZE,
364 mi->data + mi->size - MEM_FILLER_SIZE, 2 * MEM_FILLER_SIZE );
365 fputc('\n',mem_log);
366 fflush(mem_log);
367 }
368 }
369
370 ///////////////////////////////////////////////////////////////////////////////
371
FindMemInfoHelper(u8 * data,uint size)372 uint FindMemInfoHelper ( u8 * data, uint size )
373 {
374 int beg = 0;
375 int end = mem_used - 1;
376 while ( beg <= end )
377 {
378 uint idx = (beg+end)/2;
379 mem_info_t * mi = mem_list + idx;
380 if ( data < mi->data )
381 end = idx - 1 ;
382 else if ( data > mi->data )
383 beg = idx + 1;
384 else if ( size < mi->size )
385 end = idx - 1 ;
386 else if ( size > mi->size )
387 beg = idx + 1;
388 else
389 {
390 noTRACE("FindMemMapHelper(%llx,%llx) FOUND=%d/%d/%d\n",
391 (u64)off, (u64)size, idx, mem_used, mem_size );
392 return idx;
393 }
394 }
395
396 noTRACE("FindStringFieldHelper(%llx,%llx) failed=%d/%d/%d\n",
397 (u64)off, (u64)size, beg, mem_used, mem_size );
398 return beg;
399 }
400
401 ///////////////////////////////////////////////////////////////////////////////
402 ///////////////////////////////////////////////////////////////////////////////
403
InitializeTraceAlloc()404 void InitializeTraceAlloc()
405 {
406 static bool done = false;
407 if (done)
408 return;
409 done = true;
410
411 OpenMemLog();
412
413 memset(mem_filler,0xdc,sizeof(mem_filler));
414 mem_filler[MEM_FILLER_SIZE/2] = 0xcd;
415 mem_filler[MEM_FILLER_SIZE/3] = 0xcd;
416 }
417
418 ///////////////////////////////////////////////////////////////////////////////
419
CheckTraceAlloc(ccp func,ccp file,uint line)420 int CheckTraceAlloc ( ccp func, ccp file, uint line )
421 {
422 int count = 0;
423
424 mem_info_t *ptr, *end = mem_list + mem_used;
425 for ( ptr = mem_list; ptr < end; ptr++ )
426 {
427 if (memcmp(ptr->data-MEM_FILLER_SIZE,mem_filler,sizeof(mem_filler)))
428 {
429 MemLogItem(0,0,0,"BEG",ptr);
430 memcpy(ptr->data-MEM_FILLER_SIZE,mem_filler,sizeof(mem_filler));
431 count++;
432 }
433
434 if (memcmp(ptr->data+ptr->size,mem_filler,sizeof(mem_filler)))
435 {
436 MemLogItem(0,0,0,"END",ptr);
437 memcpy(ptr->data+ptr->size,mem_filler,sizeof(mem_filler));
438 count++;
439 }
440 }
441
442 if (count)
443 {
444 fprintf(stderr,"MEM-ERR: %u errors found -> %s() @ %s#%u\n",
445 count, func, file, line );
446 fflush(stderr);
447
448 if (OpenMemLog())
449 {
450 fprintf(mem_log,"--- %u errors found -> %s() @ %s#%u\n\n",
451 count, func, file, line );
452 fflush(mem_log);
453 }
454 }
455 return count;
456 }
457
458 ///////////////////////////////////////////////////////////////////////////////
459
DumpTraceAlloc(ccp func,ccp file,uint line,FILE * f)460 void DumpTraceAlloc ( ccp func, ccp file, uint line, FILE * f )
461 {
462 CheckTraceAlloc(func,file,line);
463
464 if (!f)
465 return;
466
467 fprintf(f,"---- MEM-DUMP [N=%u] -----\n",mem_used);
468 mem_info_t *ptr, *end = mem_list + mem_used;
469 for ( ptr = mem_list; ptr < end; ptr++ )
470 {
471 ccp file = strrchr(ptr->file,'/');
472 file = file ? file+1 : ptr->file;
473 fprintf(f,"%5u %p %5u %-20.20s %5u %-.25s\n",
474 ptr->seqnum, ptr->data, ptr->size,
475 ptr->func, ptr->line, file );
476 }
477 fflush(stderr);
478 }
479
480 ///////////////////////////////////////////////////////////////////////////////
481
RegisterAlloc(ccp func,ccp file,uint line,u8 * data,uint size)482 static mem_info_t * RegisterAlloc
483 ( ccp func, ccp file, uint line, u8 * data, uint size )
484 {
485 if (!mem_seqnum)
486 InitializeTraceAlloc();
487
488 memcpy(data-MEM_FILLER_SIZE,mem_filler,MEM_FILLER_SIZE);
489 memcpy(data+size,mem_filler,MEM_FILLER_SIZE);
490
491 uint idx = FindMemInfoHelper(data,size);
492
493 ASSERT( mem_used <= mem_size );
494 if ( mem_used == mem_size )
495 {
496 mem_size += 1000 + mem_size/2;
497 const uint alloc_size = mem_size * sizeof(*mem_list);
498 mem_list = realloc(mem_list,alloc_size);
499 if (!mem_list)
500 PRINT_OOM("Out of memory while RegisterAlloc() %u bytes (0x%x)\n",
501 alloc_size, alloc_size );
502 }
503
504 DASSERT( idx <= mem_used );
505 mem_info_t * mi = mem_list + idx;
506 memmove(mi+1,mi,(mem_used-idx)*sizeof(*mi));
507 mem_used++;
508
509 mi->func = func;
510 mi->file = file;
511 mi->line = line;
512 mi->data = data;
513 mi->size = size;
514 mi->seqnum = mem_seqnum++;
515
516 #if TRACE_ALLOC_MODE > 3
517 MemLog(func,file,line,"ALLOCED",data,true);
518 #endif
519 return mi;
520 }
521
522 //
523 ///////////////////////////////////////////////////////////////////////////////
524 #endif // TRACE_ALLOC_MODE > 2
525 ///////////////////////////////////////////////////////////////////////////////
526 ///////////////////////////////////////////////////////////////////////////////
527
UnregisterAlloc(ccp func,ccp file,uint line,u8 * data)528 static void * UnregisterAlloc ( ccp func, ccp file, uint line, u8 * data )
529 {
530 #if TRACE_ALLOC_MODE > 2
531 if (!data)
532 return 0;
533
534 int beg = 0;
535 int end = mem_used - 1;
536 while ( beg <= end )
537 {
538 uint idx = (beg+end)/2;
539 mem_info_t * mi = mem_list + idx;
540 if ( data < mi->data )
541 end = idx - 1 ;
542 else if ( data > mi->data )
543 beg = idx + 1;
544 else
545 {
546 #if TRACE_ALLOC_MODE > 3
547 MemLog(func,file,line,"FREE",data,true);
548 #endif
549
550 if (memcmp(data-MEM_FILLER_SIZE,mem_filler,sizeof(mem_filler)))
551 MemLogItem(func,file,line,"BEG",mi);
552
553 if (memcmp(data+mi->size,mem_filler,sizeof(mem_filler)))
554 MemLogItem(func,file,line,"END",mi);
555
556 memmove(mi,mi+1,(--mem_used-idx)*sizeof(*mi));
557 return data - MEM_FILLER_SIZE;
558 }
559 }
560 MemLog(func,file,line,"NOT FOUND",data,false);
561 #endif
562 return data;
563 }
564
565 ///////////////////////////////////////////////////////////////////////////////
566
trace_free(ccp func,ccp file,uint line,void * ptr)567 void trace_free ( ccp func, ccp file, uint line, void * ptr )
568 {
569 free(UnregisterAlloc(func,file,line,ptr));
570 }
571
572 ///////////////////////////////////////////////////////////////////////////////
573
trace_malloc(ccp func,ccp file,uint line,size_t size)574 void * trace_malloc ( ccp func, ccp file, uint line, size_t size )
575 {
576 u8 * res = malloc( size + 2 * MEM_FILLER_SIZE );
577 if (!res)
578 PRINT_OOM("Out of memory while allocate %zu+%u bytes (0x%zx)\n",
579 size, 2 * MEM_FILLER_SIZE, size + 2 * MEM_FILLER_SIZE );
580
581 res += MEM_FILLER_SIZE;
582 #if TRACE_ALLOC_MODE > 2
583 RegisterAlloc(func,file,line,res,size);
584 #endif
585 return res;
586 }
587
588 ///////////////////////////////////////////////////////////////////////////////
589
trace_calloc(ccp func,ccp file,uint line,size_t nmemb,size_t size)590 void * trace_calloc ( ccp func, ccp file, uint line, size_t nmemb, size_t size )
591 {
592 uint total_size = nmemb * size;
593 void * res = trace_malloc(func,file,line,total_size);
594 memset(res,0,total_size);
595 return res;
596 }
597
598 ///////////////////////////////////////////////////////////////////////////////
599
trace_realloc(ccp func,ccp file,uint line,void * ptr,size_t size)600 void * trace_realloc ( ccp func, ccp file, uint line, void *ptr, size_t size )
601 {
602 ptr = UnregisterAlloc(func,file,line,ptr);
603 u8 * res = realloc( ptr, size + 2 * MEM_FILLER_SIZE );
604 if (!res)
605 PRINT_OOM("Out of memory while re allocate %zu+%u bytes (0x%zx)\n",
606 size, 2 * MEM_FILLER_SIZE, size + 2 * MEM_FILLER_SIZE );
607
608 res += MEM_FILLER_SIZE;
609 #if TRACE_ALLOC_MODE > 2
610 RegisterAlloc(func,file,line,res,size);
611 #endif
612 return res;
613 }
614
615 ///////////////////////////////////////////////////////////////////////////////
616
trace_strdup(ccp func,ccp file,uint line,ccp src)617 char * trace_strdup ( ccp func, ccp file, uint line, ccp src )
618 {
619 const uint len = src ? strlen(src)+1 : 0;
620 char * res = trace_malloc(func,file,line,len);
621 memcpy(res,src,len);
622 return res;
623 }
624
625 ///////////////////////////////////////////////////////////////////////////////
626
trace_strdup2(ccp func,ccp file,uint line,ccp src1,ccp src2)627 char * trace_strdup2 ( ccp func, ccp file, uint line, ccp src1, ccp src2 )
628 {
629 const uint len1 = src1 ? strlen(src1) : 0;
630 const uint len2 = src2 ? strlen(src2) : 0;
631 char * res = trace_malloc(func,file,line,len1+len2+1);
632 if (len1)
633 memcpy(res,src1,len1);
634 if (len2)
635 memcpy(res+len1,src2,len2);
636 res[len1+len2] = 0;
637 return res;
638 }
639
640 ///////////////////////////////////////////////////////////////////////////////
641
trace_strdup3(ccp func,ccp file,uint line,ccp src1,ccp src2,ccp src3)642 char * trace_strdup3 ( ccp func, ccp file, uint line, ccp src1, ccp src2, ccp src3 )
643 {
644 const uint len1 = src1 ? strlen(src1) : 0;
645 const uint len2 = src2 ? strlen(src2) : 0;
646 const uint len3 = src3 ? strlen(src3) : 0;
647 char * res = trace_malloc(func,file,line,len1+len2+len3+1);
648 char * dest = res;
649 if (len1)
650 {
651 memcpy(dest,src1,len1);
652 dest += len1;
653 }
654 if (len2)
655 {
656 memcpy(dest,src2,len2);
657 dest += len2;
658 }
659 if (len3)
660 {
661 memcpy(dest,src3,len3);
662 dest += len3;
663 }
664 *dest = 0;
665 return res;
666 }
667
668 ///////////////////////////////////////////////////////////////////////////////
669
trace_memdup(ccp func,ccp file,uint line,const void * src,size_t copylen)670 void * trace_memdup ( ccp func, ccp file, uint line, const void * src, size_t copylen )
671 {
672 char * dest = trace_malloc(func,file,line,copylen+1);
673 memcpy(dest,src,copylen);
674 dest[copylen] = 0;
675 return dest;
676 }
677
678 //
679 ///////////////////////////////////////////////////////////////////////////////
680 /////////////// mem check ///////////////
681 ///////////////////////////////////////////////////////////////////////////////
682
683 static u8 mem_check_buf[0x100];
684 static const void * mem_check_ptr = 0;
685 static uint mem_check_size = 0;
686
687 ///////////////////////////////////////////////////////////////////////////////
688
MemCheckSetup(const void * ptr,uint size)689 void MemCheckSetup ( const void * ptr, uint size )
690 {
691 if ( ptr && size > 0 )
692 {
693 mem_check_ptr = ptr;
694 if ( size > sizeof(mem_check_buf) )
695 {
696 ERROR0(ERR_WARNING,
697 "MemCheckSetup(), max watch size = %zx (<%x)",
698 sizeof(mem_check_buf), size );
699 size = sizeof(mem_check_buf);
700 }
701 mem_check_size = size;
702 memcpy(mem_check_buf,ptr,size);
703 }
704 else
705 mem_check_size = 0;
706 }
707
708 ///////////////////////////////////////////////////////////////////////////////
709
MemCheck(ccp func,ccp file,uint line)710 void MemCheck ( ccp func, ccp file, uint line )
711 {
712 if (!mem_check_size)
713 return;
714
715 if ( memcmp(mem_check_buf,mem_check_ptr,mem_check_size) )
716 {
717 fprintf(stderr,"--- MemCheck: %p should be:\n",mem_check_ptr);
718 HexDump16(stderr,0,0,mem_check_buf,mem_check_size);
719 fprintf(stderr,"--- MemCheck: ... but is:\n");
720 HexDump16(stderr,0,0,mem_check_ptr,mem_check_size);
721
722 TRACE("--- MemCheck: %p should be:\n",mem_check_ptr);
723 TRACE_HEXDUMP16(0,0,mem_check_buf,mem_check_size);
724 TRACE("--- MemCheck: ... but is:\n");
725 TRACE_HEXDUMP16(0,0,mem_check_ptr,mem_check_size);
726
727 PrintError(func,file,line,0,ERR_FATAL,"MemCheck() failed!\n");
728 }
729 else
730 TRACE("MemCheck OK: %s @ %s#%u\n",func,file,line);
731 }
732
733 //
734 ///////////////////////////////////////////////////////////////////////////////
735 /////////////// END ///////////////
736 ///////////////////////////////////////////////////////////////////////////////
737