1
/* Copyright (c) 2005 PrimeBase Technologies GmbH
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
* 2005-01-04 Paul McCullagh
24
#include "xt_config.h"
31
#include "pthread_xt.h"
32
#include "thread_xt.h"
33
#include "strutil_xt.h"
53
void *xt_malloc(XTThreadPtr self, size_t size);
54
void *xt_calloc(XTThreadPtr self, size_t size);
55
xtBool xt_realloc(XTThreadPtr self, void **ptr, size_t size);
56
void xt_free(XTThreadPtr self, void *ptr);
57
void xt_pfree(XTThreadPtr self, void **ptr);
59
void *xt_malloc_ns(size_t size);
60
void *xt_calloc_ns(size_t size);
61
xtBool xt_realloc_ns(void **ptr, size_t size);
62
void xt_free_ns(void *ptr);
64
#define ADD_TOTAL_ALLOCS 4000
66
#define SHIFT_RIGHT(ptr, n) memmove(((char *) (ptr)) + sizeof(MissingMemoryRec), (ptr), (long) (n) * sizeof(MissingMemoryRec))
67
#define SHIFT_LEFT(ptr, n) memmove((ptr), ((char *) (ptr)) + sizeof(MissingMemoryRec), (long) (n) * sizeof(MissingMemoryRec))
69
#define STACK_TRACE_DEPTH 4
71
typedef struct MissingMemory {
77
c_char *mm_func[STACK_TRACE_DEPTH];
78
} MissingMemoryRec, *MissingMemoryPtr;
80
static MissingMemoryRec *mm_addresses = NULL;
81
static long mm_nr_in_use = 0L;
82
static long mm_total_allocated = 0L;
83
static xtWord4 mm_alloc_count = 0;
84
static xt_mutex_type mm_mutex;
87
static long mm_find_pointer(void *ptr);
93
* -----------------------------------------------------------------------
94
* STANDARD SYSTEM BASED MEMORY ALLOCATION
97
xtPublic void *xt_malloc(XTThreadPtr self, size_t size)
101
if (!(ptr = malloc(size))) {
102
xt_throw_errno(XT_CONTEXT, XT_ENOMEM);
108
xtPublic xtBool xt_realloc(XTThreadPtr self, void **ptr, size_t size)
112
if (!(new_ptr = realloc(*ptr, size))) {
113
xt_throw_errno(XT_CONTEXT, XT_ENOMEM);
120
xtPublic void xt_free(XTThreadPtr XT_UNUSED(self), void *ptr)
125
xtPublic void *xt_calloc(XTThreadPtr self, size_t size)
129
if ((ptr = xt_malloc(self, size)))
130
memset(ptr, 0, size);
136
xtPublic void xt_pfree(XTThreadPtr self, void **ptr)
147
* -----------------------------------------------------------------------
148
* SYSTEM MEMORY ALLOCATION WITH A THREAD
151
xtPublic void *xt_malloc_ns(size_t size)
155
if (!(ptr = malloc(size))) {
156
xt_register_errno(XT_REG_CONTEXT, XT_ENOMEM);
162
xtPublic void *xt_calloc_ns(size_t size)
166
if (!(ptr = malloc(size))) {
167
xt_register_errno(XT_REG_CONTEXT, XT_ENOMEM);
170
memset(ptr, 0, size);
174
xtPublic xtBool xt_realloc_ns(void **ptr, size_t size)
178
if (!(new_ptr = realloc(*ptr, size)))
179
return xt_register_errno(XT_REG_CONTEXT, XT_ENOMEM);
184
xtPublic void xt_free_ns(void *ptr)
192
* -----------------------------------------------------------------------
193
* MEMORY SEARCHING CODE
196
#define MM_THROW_ASSERTION(str) mm_throw_assertion(self, __FUNC__, __FILE__, __LINE__, str)
198
static void mm_throw_assertion(XTThreadPtr self, c_char *func, c_char *file, u_int line, c_char *str)
200
printf("***** MM:FATAL %s\n", str);
201
xt_throw_assertion(self, func, file, line, str);
205
* -----------------------------------------------------------------------
206
* MEMORY SEARCHING CODE
209
static int mm_debug_ik_inc;
210
static int mm_debug_ik_dec;
211
static int mm_debug_ik_no;
213
xtPublic void mm_trace_print_id(void *ptr)
219
xt_lock_mutex_ns(&mm_mutex);
221
mm = mm_find_pointer(ptr);
223
MissingMemoryPtr mm_ptr;
225
mm_ptr = &mm_addresses[mm];
226
printf("MM: %08lX (#%ld) %s:%d\n",
227
(unsigned long) mm_ptr->mm_ptr,
229
xt_last_name_of_path(mm_ptr->mm_file),
230
(int) mm_ptr->line_nr);
232
xt_unlock_mutex_ns(&mm_mutex);
237
* Call this function where the missing memory
240
xtPublic void mm_trace_inc(XTThreadPtr self, XTMMTraceRefPtr tr)
245
if (xt_lock_mutex(self, &mm_mutex)) {
248
mm = mm_find_pointer(tr);
250
mm_addresses[mm].trace_count = 1;
251
xt_unlock_mutex(self, &mm_mutex);
255
if (tr->mm_pos < XT_MM_STACK_TRACE-1) {
256
tr->mm_trace[tr->mm_pos++] = self->t_name[0] == 'S' ? XT_MM_TRACE_SW_INC : XT_MM_TRACE_INC;
257
for (i=1; i<=XT_MM_TRACE_DEPTH; i++) {
258
if (self->t_call_top-i < 0)
260
if (tr->mm_pos < XT_MM_STACK_TRACE-1) {
261
tr->mm_line[tr->mm_pos] = self->t_call_stack[self->t_call_top-i].cs_line;
262
tr->mm_trace[tr->mm_pos++] = self->t_call_stack[self->t_call_top-i].cs_func;
264
else if (tr->mm_pos < XT_MM_STACK_TRACE)
265
tr->mm_trace[tr->mm_pos++] = XT_MM_TRACE_ERROR;
268
else if (tr->mm_pos < XT_MM_STACK_TRACE)
269
tr->mm_trace[tr->mm_pos++] = XT_MM_TRACE_ERROR;
272
xtPublic void mm_trace_dec(XTThreadPtr self, XTMMTraceRefPtr tr)
277
if (xt_lock_mutex(self, &mm_mutex)) {
280
mm = mm_find_pointer(tr);
282
mm_addresses[mm].trace_count = 1;
283
xt_unlock_mutex(self, &mm_mutex);
287
if (tr->mm_pos < XT_MM_STACK_TRACE-1) {
288
tr->mm_trace[tr->mm_pos++] = self->t_name[0] == 'S' ? XT_MM_TRACE_SW_DEC : XT_MM_TRACE_DEC;
289
for (i=1; i<=XT_MM_TRACE_DEPTH; i++) {
290
if (self->t_call_top-i < 0)
292
if (tr->mm_pos < XT_MM_STACK_TRACE-1) {
293
tr->mm_line[tr->mm_pos] = self->t_call_stack[self->t_call_top-i].cs_line;
294
tr->mm_trace[tr->mm_pos++] = self->t_call_stack[self->t_call_top-i].cs_func;
296
else if (tr->mm_pos < XT_MM_STACK_TRACE)
297
tr->mm_trace[tr->mm_pos++] = XT_MM_TRACE_ERROR;
300
else if (tr->mm_pos < XT_MM_STACK_TRACE)
301
tr->mm_trace[tr->mm_pos++] = XT_MM_TRACE_ERROR;
304
xtPublic void mm_trace_init(XTThreadPtr self, XTMMTraceRefPtr tr)
307
tr->mm_id = (u_int) mm_debug_ik_no;
309
mm_trace_inc(self, tr);
312
xtPublic void mm_trace_print(XTMMTraceRefPtr tr)
316
for (i=0; i<tr->mm_pos; i++) {
317
if (tr->mm_trace[i] == XT_MM_TRACE_INC) {
321
printf("INC (%d) ", cnt);
323
else if (tr->mm_trace[i] == XT_MM_TRACE_SW_INC) {
326
printf("SW-DEC (%d) ", cnt);
329
else if (tr->mm_trace[i] == XT_MM_TRACE_DEC) {
332
printf("DEC (%d) ", cnt);
335
else if (tr->mm_trace[i] == XT_MM_TRACE_SW_DEC) {
338
printf("SW-DEC (%d) ", cnt);
341
else if (tr->mm_trace[i] == XT_MM_TRACE_ERROR) {
344
printf("ERROR: Space out");
347
printf("%s(%d) ", tr->mm_trace[i], (int) tr->mm_line[i]);
352
/* Call this function on exit, when you know the memory is missing. */
353
static void mm_debug_trace_count(XTMMTraceRefPtr tr)
355
printf("MM Trace ID: %d\n", tr->mm_id);
359
/* The give the sum of allocations, etc. */
360
static void mm_debug_trace_sum(void)
362
if (mm_debug_ik_no) {
363
printf("MM Trace INC: %d\n", mm_debug_ik_inc);
364
printf("MM Trace DEC: %d\n", mm_debug_ik_dec);
365
printf("MM Trace ALL: %d\n", mm_debug_ik_no);
370
* -----------------------------------------------------------------------
371
* DEBUG MEMORY ALLOCATION AND HEAP CHECKING
375
static long mm_find_pointer(void *ptr)
377
register long i, n, guess;
382
guess = (i + n - 1) >> 1;
383
if (ptr == mm_addresses[guess].mm_ptr)
385
if (ptr < mm_addresses[guess].mm_ptr)
393
static long mm_add_pointer(void *ptr, u_int XT_UNUSED(id))
395
register int i, n, guess;
397
if (mm_nr_in_use == mm_total_allocated) {
398
/* Not enough space, add more: */
399
MissingMemoryRec *new_addresses;
401
new_addresses = (MissingMemoryRec *) xt_calloc_ns(sizeof(MissingMemoryRec) * (mm_total_allocated + ADD_TOTAL_ALLOCS));
406
memcpy(new_addresses, mm_addresses, sizeof(MissingMemoryRec) * mm_total_allocated);
410
mm_addresses = new_addresses;
411
mm_total_allocated += ADD_TOTAL_ALLOCS;
417
guess = (i + n - 1) >> 1;
418
if (ptr < mm_addresses[guess].mm_ptr)
424
SHIFT_RIGHT(&mm_addresses[i], mm_nr_in_use - i);
426
mm_addresses[i].mm_ptr = ptr;
430
xtPublic char *mm_watch_point = 0;
432
static long mm_remove_pointer(void *ptr)
434
register int i, n, guess;
436
if (mm_watch_point == ptr)
437
printf("Hit watch point!\n");
442
guess = (i + n - 1) >> 1;
443
if (ptr == mm_addresses[guess].mm_ptr)
445
if (ptr < mm_addresses[guess].mm_ptr)
453
/* Decrease the number of sets, and shift left: */
455
SHIFT_LEFT(&mm_addresses[guess], mm_nr_in_use - guess);
459
static void mm_add_core_ptr(XTThreadPtr self, void *ptr, u_int id, u_int line, c_char *file_name)
463
mm = mm_add_pointer(ptr, id);
465
MM_THROW_ASSERTION("MM ERROR: Cannot allocate table big enough!");
469
/* Record the pointer: */
470
if (mm_alloc_count >= 297 && mm_alloc_count <= 340) {
472
mm_addresses[mm].id = id;
474
mm_addresses[mm].id = mm_alloc_count++;
478
mm_addresses[mm].id = id;
480
mm_addresses[mm].id = mm_alloc_count++;
482
mm_addresses[mm].mm_ptr = ptr;
483
mm_addresses[mm].line_nr = (ushort) line;
485
mm_addresses[mm].mm_file = file_name;
487
mm_addresses[mm].mm_file = "?";
489
for (int i=1; i<=STACK_TRACE_DEPTH; i++) {
490
if (self->t_call_top-i >= 0)
491
mm_addresses[mm].mm_func[i-1] = self->t_call_stack[self->t_call_top-i].cs_func;
493
mm_addresses[mm].mm_func[i-1] = NULL;
497
for (int i=0; i<STACK_TRACE_DEPTH; i++)
498
mm_addresses[mm].mm_func[i] = NULL;
502
static void mm_remove_core_ptr(void *ptr)
504
XTThreadPtr self = NULL;
507
mm = mm_remove_pointer(ptr);
509
MM_THROW_ASSERTION("Pointer not allocated");
514
static void mm_throw_assertion(MissingMemoryPtr mm_ptr, void *p, c_char *message);
516
static long mm_find_core_ptr(void *ptr)
520
mm = mm_find_pointer(ptr);
522
mm_throw_assertion(NULL, ptr, "Pointer not allocated");
526
static void mm_replace_core_ptr(long i, void *ptr)
528
XTThreadPtr self = NULL;
529
MissingMemoryRec tmp = mm_addresses[i];
532
mm_remove_pointer(mm_addresses[i].mm_ptr);
533
mm = mm_add_pointer(ptr, mm_addresses[i].id);
535
MM_THROW_ASSERTION("Cannot allocate table big enough!");
538
mm_addresses[mm] = tmp;
539
mm_addresses[mm].mm_ptr = ptr;
543
static void mm_throw_assertion(MissingMemoryPtr mm_ptr, void *p, c_char *message)
545
XTThreadPtr self = NULL;
549
sprintf(str, "MM: %08lX (#%ld) %s:%d %s",
550
(unsigned long) mm_ptr->mm_ptr,
552
xt_last_name_of_path(mm_ptr->mm_file),
553
(int) mm_ptr->line_nr,
557
sprintf(str, "MM: %08lX %s", (unsigned long) p, message);
558
MM_THROW_ASSERTION(str);
562
* -----------------------------------------------------------------------
563
* MISSING MEMORY PUBLIC ROUTINES
566
#define MEM_DEBUG_HDR_SIZE offsetof(MemoryDebugRec, data)
567
#define MEM_TRAILER_SIZE 2
568
#define MEM_HEADER 0x01010101
569
#define MEM_FREED 0x03030303
570
#define MEM_TRAILER_BYTE 0x02
571
#define MEM_FREED_BYTE 0x03
573
typedef struct MemoryDebug {
577
} MemoryDebugRec, *MemoryDebugPtr;
579
static size_t mm_checkmem(XTThreadPtr self, MissingMemoryPtr mm_ptr, void *p, xtBool freeme)
581
unsigned char *ptr = (unsigned char *) p - MEM_DEBUG_HDR_SIZE;
582
MemoryDebugPtr debug_ptr = (MemoryDebugPtr) ptr;
583
size_t size = debug_ptr->size;
584
long a_value; /* Added to simplfy debugging. */
588
if (!ASSERT(((long) p & 1L) == 0))
591
if (debug_ptr->check == MEM_FREED) {
592
mm_throw_assertion(mm_ptr, p, "Pointer already freed 'debug_ptr->check != MEM_FREED'");
595
a_value = MEM_HEADER;
596
if (debug_ptr->check != MEM_HEADER) {
597
mm_throw_assertion(mm_ptr, p, "Header not valid 'debug_ptr->check != MEM_HEADER'");
600
a_value = MEM_TRAILER_BYTE;
601
if (!(*((unsigned char *) ptr + size + MEM_DEBUG_HDR_SIZE) == MEM_TRAILER_BYTE &&
602
*((unsigned char *) ptr + size + MEM_DEBUG_HDR_SIZE + 1L) == MEM_TRAILER_BYTE)) {
603
mm_throw_assertion(mm_ptr, p, "Trailer overwritten");
608
debug_ptr->check = MEM_FREED;
609
*((unsigned char *) ptr + size + MEM_DEBUG_HDR_SIZE) = MEM_FREED_BYTE;
610
*((unsigned char *) ptr + size + MEM_DEBUG_HDR_SIZE + 1L) = MEM_FREED_BYTE;
612
memset(((unsigned char *) ptr) + MEM_DEBUG_HDR_SIZE, 0xF5, size);
619
xtBool xt_mm_scan_core(void)
626
if (!xt_lock_mutex(NULL, &mm_mutex))
629
for (mm=0; mm<mm_nr_in_use; mm++) {
630
mm_checkmem(NULL, &mm_addresses[mm], mm_addresses[mm].mm_ptr, FALSE);
633
xt_unlock_mutex(NULL, &mm_mutex);
637
void xt_mm_memmove(void *block, void *dest, void *source, size_t size)
640
MemoryDebugPtr debug_ptr = (MemoryDebugPtr) ((char *) block - MEM_DEBUG_HDR_SIZE);
643
if (xt_lock_mutex(NULL, &mm_mutex)) {
644
mm_find_core_ptr(block);
645
xt_unlock_mutex(NULL, &mm_mutex);
648
mm_checkmem(NULL, NULL, block, FALSE);
650
if (dest < block || (char *) dest > (char *) block + debug_ptr->size)
651
mm_throw_assertion(NULL, block, "Destination not in block");
652
if ((char *) dest + size > (char *) block + debug_ptr->size)
653
mm_throw_assertion(NULL, block, "Copy will overwrite memory");
656
memmove(dest, source, size);
659
void xt_mm_memcpy(void *block, void *dest, void *source, size_t size)
662
MemoryDebugPtr debug_ptr = (MemoryDebugPtr) ((char *) block - MEM_DEBUG_HDR_SIZE);
665
if (xt_lock_mutex(NULL, &mm_mutex)) {
666
mm_find_core_ptr(block);
667
xt_unlock_mutex(NULL, &mm_mutex);
670
mm_checkmem(NULL, NULL, block, FALSE);
672
if (dest < block || (char *) dest > (char *) block + debug_ptr->size)
673
mm_throw_assertion(NULL, block, "Destination not in block");
674
if ((char *) dest + size > (char *) block + debug_ptr->size)
675
mm_throw_assertion(NULL, block, "Copy will overwrite memory");
678
memcpy(dest, source, size);
681
void xt_mm_memset(void *block, void *dest, int value, size_t size)
684
MemoryDebugPtr debug_ptr = (MemoryDebugPtr) ((char *) block - MEM_DEBUG_HDR_SIZE);
687
if (xt_lock_mutex(NULL, &mm_mutex)) {
688
mm_find_core_ptr(block);
689
xt_unlock_mutex(NULL, &mm_mutex);
692
mm_checkmem(NULL, NULL, block, FALSE);
694
if (dest < block || (char *) dest > (char *) block + debug_ptr->size)
695
mm_throw_assertion(NULL, block, "Destination not in block");
696
if ((char *) dest + size > (char *) block + debug_ptr->size)
697
mm_throw_assertion(NULL, block, "Copy will overwrite memory");
700
memset(dest, value, size);
703
void *xt_mm_malloc(XTThreadPtr self, size_t size, u_int line, c_char *file)
707
if (size > (600*1024*1024))
708
mm_throw_assertion(NULL, NULL, "Very large block allocated - meaybe error");
709
p = (unsigned char *) xt_malloc(self, size + MEM_DEBUG_HDR_SIZE + MEM_TRAILER_SIZE);
713
memset(p, 0x55, size + MEM_DEBUG_HDR_SIZE + MEM_TRAILER_SIZE);
715
((MemoryDebugPtr) p)->check = MEM_HEADER;
716
((MemoryDebugPtr) p)->size = size;
717
*(p + size + MEM_DEBUG_HDR_SIZE) = MEM_TRAILER_BYTE;
718
*(p + size + MEM_DEBUG_HDR_SIZE + 1L) = MEM_TRAILER_BYTE;
723
xt_lock_mutex(self, &mm_mutex);
724
mm_add_core_ptr(self, p + MEM_DEBUG_HDR_SIZE, 0, line, file);
725
xt_unlock_mutex(self, &mm_mutex);
728
return p + MEM_DEBUG_HDR_SIZE;
731
void *xt_mm_calloc(XTThreadPtr self, size_t size, u_int line, c_char *file)
735
if (size > (500*1024*1024))
736
mm_throw_assertion(NULL, NULL, "Very large block allocated - meaybe error");
737
p = (unsigned char *) xt_calloc(self, size + MEM_DEBUG_HDR_SIZE + MEM_TRAILER_SIZE);
741
((MemoryDebugPtr) p)->check = MEM_HEADER;
742
((MemoryDebugPtr) p)->size = size;
743
*(p + size + MEM_DEBUG_HDR_SIZE) = MEM_TRAILER_BYTE;
744
*(p + size + MEM_DEBUG_HDR_SIZE + 1L) = MEM_TRAILER_BYTE;
749
xt_lock_mutex(self, &mm_mutex);
750
mm_add_core_ptr(self, p + MEM_DEBUG_HDR_SIZE, 0, line, file);
751
xt_unlock_mutex(self, &mm_mutex);
754
return p + MEM_DEBUG_HDR_SIZE;
757
xtBool xt_mm_sys_realloc(XTThreadPtr self, void **ptr, size_t newsize, u_int line, c_char *file)
759
return xt_mm_realloc(self, ptr, newsize, line, file);
762
xtBool xt_mm_realloc(XTThreadPtr self, void **ptr, size_t newsize, u_int line, c_char *file)
764
unsigned char *oldptr = (unsigned char *) *ptr;
772
*ptr = xt_mm_malloc(self, newsize, line, file);
773
return *ptr ? TRUE : FALSE;
777
xt_lock_mutex(self, &mm_mutex);
778
if ((mm = mm_find_core_ptr(oldptr)) < 0) {
779
xt_unlock_mutex(self, &mm_mutex);
780
xt_throw_errno(XT_CONTEXT, XT_ENOMEM);
783
xt_unlock_mutex(self, &mm_mutex);
786
oldptr = oldptr - MEM_DEBUG_HDR_SIZE;
787
size = ((MemoryDebugPtr) oldptr)->size;
789
ASSERT(((MemoryDebugPtr) oldptr)->check == MEM_HEADER);
790
ASSERT(*((unsigned char *) oldptr + size + MEM_DEBUG_HDR_SIZE) == MEM_TRAILER_BYTE &&
791
*((unsigned char *) oldptr + size + MEM_DEBUG_HDR_SIZE + 1L) == MEM_TRAILER_BYTE);
793
/* Realloc allways moves! */
794
pnew = (unsigned char *) xt_malloc(self, newsize + MEM_DEBUG_HDR_SIZE + MEM_TRAILER_SIZE);
796
xt_throw_errno(XT_CONTEXT, XT_ENOMEM);
800
if (newsize > size) {
801
memcpy(((MemoryDebugPtr) pnew)->data, ((MemoryDebugPtr) oldptr)->data, size);
802
memset(((MemoryDebugPtr) pnew)->data + size, 0x55, newsize - size);
805
memcpy(((MemoryDebugPtr) pnew)->data, ((MemoryDebugPtr) oldptr)->data, newsize);
807
((MemoryDebugPtr) pnew)->check = MEM_HEADER;
808
((MemoryDebugPtr) pnew)->size = newsize;
809
*(pnew + newsize + MEM_DEBUG_HDR_SIZE) = MEM_TRAILER_BYTE;
810
*(pnew + newsize + MEM_DEBUG_HDR_SIZE + 1L) = MEM_TRAILER_BYTE;
813
xt_lock_mutex(self, &mm_mutex);
814
if ((mm = mm_find_core_ptr(oldptr + MEM_DEBUG_HDR_SIZE)) < 0) {
815
xt_unlock_mutex(self, &mm_mutex);
816
xt_throw_errno(XT_CONTEXT, XT_ENOMEM);
819
mm_replace_core_ptr(mm, pnew + MEM_DEBUG_HDR_SIZE);
820
xt_unlock_mutex(self, &mm_mutex);
823
memset(oldptr, 0x55, size + MEM_DEBUG_HDR_SIZE + MEM_TRAILER_SIZE);
824
xt_free(self, oldptr);
826
*ptr = pnew + MEM_DEBUG_HDR_SIZE;
830
void xt_mm_free(XTThreadPtr self, void *ptr)
833
if (xt_lock_mutex(self, &mm_mutex)) {
834
mm_remove_core_ptr(ptr);
835
xt_unlock_mutex(self, &mm_mutex);
838
mm_checkmem(self, NULL, ptr, TRUE);
841
void xt_mm_pfree(XTThreadPtr self, void **ptr)
851
size_t xt_mm_malloc_size(XTThreadPtr self, void *ptr)
856
if (xt_lock_mutex(self, &mm_mutex)) {
857
mm_find_core_ptr(ptr);
858
xt_unlock_mutex(self, &mm_mutex);
861
size = mm_checkmem(self, NULL, ptr, FALSE);
865
void xt_mm_check_ptr(XTThreadPtr self, void *ptr)
867
mm_checkmem(self, NULL, ptr, FALSE);
872
* -----------------------------------------------------------------------
876
xtPublic xtBool xt_init_memory(void)
879
XTThreadPtr self = NULL;
881
if (!xt_init_mutex_with_autoname(NULL, &mm_mutex))
884
mm_addresses = (MissingMemoryRec *) malloc(sizeof(MissingMemoryRec) * ADD_TOTAL_ALLOCS);
886
MM_THROW_ASSERTION("MM ERROR: Insuffient memory to allocate MM table");
887
xt_free_mutex(&mm_mutex);
891
memset(mm_addresses, 0, sizeof(MissingMemoryRec) * ADD_TOTAL_ALLOCS);
892
mm_total_allocated = ADD_TOTAL_ALLOCS;
899
xtPublic void debug_ik_count(void *value);
900
xtPublic void debug_ik_sum(void);
902
xtPublic void xt_exit_memory(void)
911
xt_lock_mutex(NULL, &mm_mutex);
912
for (mm=0; mm<mm_nr_in_use; mm++) {
913
MissingMemoryPtr mm_ptr = &mm_addresses[mm];
915
xt_logf(XT_NS_CONTEXT, XT_LOG_FATAL, "MM: %p (#%ld) %s:%d Not freed\n",
918
xt_last_name_of_path(mm_ptr->mm_file),
919
(int) mm_ptr->line_nr);
920
for (i=0; i<STACK_TRACE_DEPTH; i++) {
921
if (mm_ptr->mm_func[i])
922
xt_logf(XT_NS_CONTEXT, XT_LOG_FATAL, "MM: %s\n", mm_ptr->mm_func[i]);
925
* Assumes we place out tracing function in the first
928
if (mm_ptr->trace_count)
929
mm_debug_trace_count((XTMMTraceRefPtr) mm_ptr->mm_ptr);
931
mm_debug_trace_sum();
935
mm_total_allocated = 0L;
937
xt_unlock_mutex(NULL, &mm_mutex);
939
xt_free_mutex(&mm_mutex);
944
* -----------------------------------------------------------------------
945
* MEMORY ALLOCATION UTILITIES
949
char *xt_mm_dup_string(XTThreadPtr self, c_char *str, u_int line, c_char *file)
951
char *xt_dup_string(XTThreadPtr self, c_char *str)
961
new_str = (char *) xt_mm_malloc(self, len + 1, line, file);
963
new_str = (char *) xt_malloc(self, len + 1);
966
strcpy(new_str, str);
970
xtPublic char *xt_long_to_str(XTThreadPtr self, long v)
974
sprintf(str, "%lu", v);
975
return xt_dup_string(self, str);
978
char *xt_dup_nstr(XTThreadPtr self, c_char *str, int start, size_t len)
980
char *new_str = (char *) xt_malloc(self, len + 1);
983
memcpy(new_str, str + start, len);
990
* -----------------------------------------------------------------------
991
* LIGHT WEIGHT CHECK FUNCTIONS
992
* Timing related memory management problems my not like the memset
993
* or other heavy checking. Try this...
996
#ifdef LIGHT_WEIGHT_CHECKS
997
xtPublic void *xt_malloc(XTThreadPtr self, size_t size)
1001
if (!(ptr = (char *) malloc(size+8))) {
1002
xt_throw_errno(XT_CONTEXT, XT_ENOMEM);
1005
*((xtWord4 *) ptr) = size;
1006
*((xtWord4 *) (ptr + size + 4)) = 0x7E7EFEFE;
1010
xtPublic void xt_check_ptr(void *ptr)
1015
old_ptr = (char *) ptr;
1017
size = *((xtWord4 *) old_ptr);
1018
if (size == 0xDEADBEAF || *((xtWord4 *) (old_ptr + size + 4)) != 0x7E7EFEFE) {
1026
xtPublic xtBool xt_realloc(XTThreadPtr self, void **ptr, size_t size)
1031
if ((old_ptr = (char *) *ptr)) {
1032
void check_for_file(char *my_ptr, xtWord4 len);
1034
xt_check_ptr(old_ptr);
1035
check_for_file((char *) old_ptr, *((xtWord4 *) (old_ptr - 4)));
1036
if (!(new_ptr = (char *) realloc(old_ptr - 4, size+8))) {
1037
xt_throw_errno(XT_CONTEXT, XT_ENOMEM);
1040
*((xtWord4 *) new_ptr) = size;
1041
*((xtWord4 *) (new_ptr + size + 4)) = 0x7E7EFEFE;
1045
*ptr = xt_malloc(self, size);
1046
return *ptr != NULL;
1049
xtPublic void xt_free(XTThreadPtr XT_UNUSED(self), void *ptr)
1053
void check_for_file(char *my_ptr, xtWord4 len);
1055
old_ptr = (char *) ptr;
1057
size = *((xtWord4 *) old_ptr);
1058
if (size == 0xDEADBEAF || *((xtWord4 *) (old_ptr + size + 4)) != 0x7E7EFEFE) {
1064
check_for_file((char *) ptr, size);
1065
*((xtWord4 *) old_ptr) = 0xDEADBEAF;
1066
*((xtWord4 *) (old_ptr + size)) = 0xEFEFDFDF;
1067
*((xtWord4 *) (old_ptr + size + 4)) = 0x1F1F1F1F;
1068
//memset(old_ptr, 0xEF, size+4);
1072
xtPublic void *xt_calloc(XTThreadPtr self, size_t size)
1076
if ((ptr = xt_malloc(self, size)))
1077
memset(ptr, 0, size);
1083
xtPublic void xt_pfree(XTThreadPtr self, void **ptr)
1093
xtPublic void *xt_malloc_ns(size_t size)
1097
if (!(ptr = (char *) malloc(size+8))) {
1098
xt_register_errno(XT_REG_CONTEXT, XT_ENOMEM);
1101
*((xtWord4 *) ptr) = size;
1102
*((xtWord4 *) (ptr + size + 4)) = 0x7E7EFEFE;
1106
xtPublic void *xt_calloc_ns(size_t size)
1110
if (!(ptr = (char *) malloc(size+8))) {
1111
xt_register_errno(XT_REG_CONTEXT, XT_ENOMEM);
1114
*((xtWord4 *) ptr) = size;
1115
*((xtWord4 *) (ptr + size + 4)) = 0x7E7EFEFE;
1116
memset(ptr+4, 0, size);
1120
xtPublic xtBool xt_realloc_ns(void **ptr, size_t size)
1125
if ((old_ptr = (char *) *ptr)) {
1126
void check_for_file(char *my_ptr, xtWord4 len);
1128
xt_check_ptr(old_ptr);
1129
check_for_file((char *) old_ptr, *((xtWord4 *) (old_ptr - 4)));
1130
if (!(new_ptr = (char *) realloc(old_ptr - 4, size+8)))
1131
return xt_register_errno(XT_REG_CONTEXT, XT_ENOMEM);
1132
*((xtWord4 *) new_ptr) = size;
1133
*((xtWord4 *) (new_ptr + size + 4)) = 0x7E7EFEFE;
1137
*ptr = xt_malloc_ns(size);
1138
return *ptr != NULL;
1141
xtPublic void xt_free_ns(void *ptr)
1145
void check_for_file(char *my_ptr, xtWord4 len);
1147
old_ptr = (char *) ptr;
1149
size = *((xtWord4 *) old_ptr);
1150
if (size == 0xDEADBEAF || *((xtWord4 *) (old_ptr + size + 4)) != 0x7E7EFEFE) {
1156
check_for_file((char *) ptr, size);
1157
*((xtWord4 *) old_ptr) = 0xDEADBEAF;
1158
*((xtWord4 *) (old_ptr + size)) = 0xEFEFDFDF;
1159
*((xtWord4 *) (old_ptr + size + 4)) = 0x1F1F1F1F;
1160
//memset(old_ptr, 0xEE, size+4);