Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/demo/jvmti/hprof/debug_malloc.c
38829 views
1
/*
2
* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
3
*
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
6
* are met:
7
*
8
* - Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
*
11
* - Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
*
15
* - Neither the name of Oracle nor the names of its
16
* contributors may be used to endorse or promote products derived
17
* from this software without specific prior written permission.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
*/
31
32
/*
33
* This source code is provided to illustrate the usage of a given feature
34
* or technique and has been deliberately simplified. Additional steps
35
* required for a production-quality application, such as security checks,
36
* input validation and proper error handling, might not be present in
37
* this sample code.
38
*/
39
40
41
/* **************************************************************************
42
*
43
* Set of malloc/realloc/calloc/strdup/free replacement macros that
44
* insert some extra words around each allocation for debugging purposes
45
* and also attempt to detect invalid uses of the malloc heap through
46
* various tricks like inserting clobber words at the head and tail of
47
* the user's area, delayed free() calls, and setting the memory to
48
* a fixed pattern on allocation and when freed. The allocations also
49
* can include warrants so that when an area is clobbered, this
50
* package can report where the allocation took place.
51
* The macros included are:
52
* malloc(size)
53
* realloc(ptr,size)
54
* calloc(nelem,elsize)
55
* strdup(s1)
56
* free(ptr)
57
* malloc_police() <--- Not a system function
58
* The above macros match the standard behavior of the system functions.
59
*
60
* They should be used through the include file "debug_malloc.h".
61
*
62
* IMPORTANT: All source files that call any of these macros
63
* should include debug_malloc.h. This package will
64
* not work if the memory isn't allocated and freed
65
* by the macros in debug_malloc.h. The important issue
66
* is that any malloc() from debug_malloc.h must be
67
* freed by the free() in debug_malloc.h.
68
*
69
* The macros in debug_malloc.h will override the normal use of
70
* malloc, realloc, calloc, strdup, and free with the functions below.
71
*
72
* These functions include:
73
* void *debug_malloc(size_t, void*, int);
74
* void *debug_realloc(void*, size_t, void*, int);
75
* void *debug_calloc(size_t, size_t, void*, int);
76
* void debug_free(void *, void*, int);
77
*
78
* In addition the function debug_malloc_police() can be called to
79
* tell you what memory has not been freed.
80
* void debug_malloc_police(void*, int);
81
* The function debug_malloc_police() is available through the macro
82
* malloc_police(). Normally you would want to call this at exit()
83
* time to find out what memory is still allocated.
84
*
85
* The variable malloc_watch determines if the warrants are generated.
86
* warrants are structures that include the filename and line number
87
* of the caller who allocated the memory. This structure is stored
88
* at the tail of the malloc space, which is allocated large enough
89
* to hold some clobber words at the head and tail, the user's request
90
* and the warrant record (if malloc_watch is non-zero).
91
*
92
* The macro LEFT_OVER_CHAR is what the trailing bytes of an allocation
93
* are set to (when the allocation is not a multiple of 8) on allocation.
94
* At free(0 time, these bytes are double checked to make sure they were
95
* not clobbered. To remove this feature #undef LEFT_OVER_CHAR.
96
*
97
* The memory freed will have the FREED_CHAR put into it. To remove this
98
* feature #undef FREED_CHAR.
99
*
100
* The memory allocated (not calloc'd) will have the ALLOC_CHAR put into it
101
* at the time of allocation. To remove this feature #undef ALLOC_CHAR.
102
*
103
* The macro MAX_FREE_DELAY_COUNT controls how many free blocks will
104
* be kept around before being freed. This creates a delayed affect
105
* so that free space that gets clobbered just might get detected.
106
* The free() call will immediately set the user space to the FREED_CHAR,
107
* leaving the clobber words and warrant in place (making sure they
108
* haven't been clobbered). Then the free() pointer is added to a
109
* queue of MAX_FREE_DELAY_COUNT long, and if the queue was full, the
110
* oldest free()'d memory is actually freed, getting it's entire
111
* memory length set to the FREED_CHAR.
112
*
113
* WARNING: This can significantly slow down an application, depending
114
* on how many allocations are made. Also the additional memory
115
* needed for the clobber words and the warrants can be significant
116
* again, depending on how many allocations are made.
117
* In addition, the delayed free calls can create situations
118
* where you might run out of memory prematurely.
119
*
120
* **************************************************************************
121
*/
122
123
#ifdef DEBUG
124
125
#include <stdio.h>
126
#include <stdlib.h>
127
#include <string.h>
128
#include <ctype.h>
129
#include <stdarg.h>
130
#include "hprof.h"
131
132
/* ***************************************************************************
133
* Space normally looks like (clobber Word is 64 bits and aligned to 8 bytes):
134
*
135
* -----------------
136
* malloc/free get->| clobber Word | ---> contains -size requested by user
137
* -----------------
138
* User gets --->| user space |
139
* | |
140
* | | left_over | ---> left_over bytes will be <= 7
141
* -----------------
142
* | clobber Word | ---> contains -size requested by user
143
* -----------------
144
* | Warrant | ---> Optional (malloc_watch!=0)
145
* | | Contains filename and line number
146
* | | where allocation happened
147
* | |
148
* -----------------
149
***************************************************************************/
150
151
/*
152
* Flag that tells debug_malloc/debug_free/debug_realloc to police
153
* heap space usage. (This is a dynamic flag that can be turned on/off)
154
*/
155
static int malloc_watch = 1;
156
157
/* Character to stuff into freed space */
158
#define FREED_CHAR 'F'
159
160
/* Character to stuff into allocated space */
161
#define ALLOC_CHAR 'A'
162
163
/* Character to stuff into left over trailing bytes */
164
#define LEFT_OVER_CHAR 'Z'
165
166
/* Number of 'free' calls that will be delayed until the end */
167
#define MAX_FREE_DELAY_COUNT 1
168
#undef MAX_FREE_DELAY_COUNT
169
170
/* Maximum name of __FILE_ stored in each malloc'd area */
171
#define WARRANT_NAME_MAX (32-1) /* 1 less than multiple of 8 is best */
172
173
/* Macro to convert a user pointer to the malloc pointer */
174
#define user2malloc_(uptr) (((char*)(void*)uptr)-sizeof(Word))
175
176
/* Macro to convert a macro pointer to the user pointer */
177
#define malloc2user_(mptr) (((char*)(void*)(mptr))+sizeof(Word))
178
179
/* Size of the warrant record (this is dynamic) */
180
#define warrant_space ( malloc_watch?sizeof(Warrant_Record):0 )
181
182
/* Macro to round up a number of bytes to a multiple of sizeof(Word) bytes */
183
#define round_up_(n) \
184
((n)==0?0:(sizeof(Word)+(((n)-1)/sizeof(Word))*sizeof(Word)))
185
186
/* Macro to calculate the needed malloc bytes from the user's request. */
187
#define rbytes_(nbytes) \
188
(size_t)( sizeof(Word) + round_up_(nbytes) + sizeof(Word) + warrant_space )
189
190
/* Macro to get the -size stored in space through the malloc pointer */
191
#define nsize1_(mptr) (((Word*)(void*)(mptr))->nsize1)
192
#define nsize2_(mptr) (((Word*)(void*)(mptr))->nsize2)
193
194
/* Macro to get the -size stored in the tail of the space through */
195
/* the malloc pointer */
196
#define tail_nsize1_(mptr) \
197
nsize1_(((char*)(void*)(mptr))+round_up_(-nsize1_(mptr))+sizeof(Word))
198
#define tail_nsize2_(mptr) \
199
nsize2_(((char*)(void*)(mptr))+round_up_(-nsize1_(mptr))+sizeof(Word))
200
201
/* Macro to get the -size stored in space through the user pointer */
202
#define user_nsize1_(uptr) nsize1_(user2malloc_(uptr))
203
#define user_nsize2_(uptr) nsize2_(user2malloc_(uptr))
204
205
/* Macro to get the -size stored in the tail of the space through */
206
/* the user pointer */
207
#define user_tail_nsize1_(uptr) tail_nsize1_(user2malloc_(uptr))
208
#define user_tail_nsize2_(uptr) tail_nsize2_(user2malloc_(uptr))
209
210
/* Macro to get the int* of the last 32bit word of user space */
211
#define last_user_word_(mptr) \
212
((int*)(((char*)(void*)(mptr))+round_up_(-nsize1_(mptr))))
213
214
/* Macros to get at the warrant contents from the malloc pointer */
215
#define warrant_(mptr) \
216
(*((Warrant_Record*)(void*)(((char*)(void*)(mptr))+round_up_(-nsize1_(mptr))+sizeof(Word)*2)))
217
218
/* This struct is allocated after the tail clobber word if malloc_watch */
219
/* is true. */
220
typedef struct {
221
void *link; /* Next mptr in list */
222
char name[WARRANT_NAME_MAX + 1]; /* Name of allocator */
223
int line; /* Line number where allocated */
224
int id; /* Nth allocation */
225
} Warrant_Record;
226
#define warrant_link_(mptr) warrant_(mptr).link
227
#define warrant_name_(mptr) warrant_(mptr).name
228
#define warrant_line_(mptr) warrant_(mptr).line
229
#define warrant_id_(mptr) warrant_(mptr).id
230
#define MFILE(mptr) (malloc_watch?warrant_name_(mptr):"?")
231
#define MLINE(mptr) (malloc_watch?warrant_line_(mptr):0)
232
#define MID(mptr) (malloc_watch?warrant_id_(mptr):0)
233
234
/* This should be one machine word and is also the clobber word struct */
235
typedef struct {
236
int nsize1;
237
int nsize2;
238
} Word; /* Largest basic type , sizeof(double)? */
239
240
/* The first malloc pointer for the warrants */
241
static void *first_warrant_mptr = NULL;
242
243
/* Counter of allocations */
244
static int id_counter = 0;
245
static int largest_size = 0;
246
static void * largest_addr = NULL;
247
static void * smallest_addr = NULL;
248
249
/* Used to isolate what the error is */
250
static char *debug_check;
251
static void *clobbered_ptr;
252
253
/* Minimum macro */
254
#define minimum(a,b) ((a)<(b)?(a):(b))
255
256
/* Message routine */
257
static void
258
error_message(const char * format, ...)
259
{
260
FILE *error_fp = stderr; /* All debug_malloc.c messages */
261
va_list ap;
262
va_start(ap, format);
263
(void)fprintf(error_fp, "debug_malloc: ");
264
(void)vfprintf(error_fp, format, ap);
265
(void)fprintf(error_fp, "\n");
266
(void)fflush(error_fp);
267
va_end(ap);
268
}
269
270
/* This function prints out a memory error for the memory function
271
* 'name' which was called in file 'file' at line number 'line'. The malloc
272
* pointer with the error is in 'mptr'.
273
*/
274
static void
275
memory_error(void *mptr, const char *name, int mid, const char *mfile, int mline, const char *file, int line)
276
{
277
char nice_words[512];
278
char temp[256];
279
int len;
280
void *mptr_walk;
281
282
if (name == NULL)
283
name = "UNKNOWN_NAME";
284
if (file == NULL)
285
file = "UNKNOWN_FILE";
286
md_system_error(temp, (int)sizeof(temp));
287
(void)strcpy(nice_words, temp);
288
if ( debug_check!=NULL ) {
289
(void)md_snprintf(nice_words, sizeof(nice_words),
290
"%s The %s at %p appears to have been hit.",
291
temp, debug_check, clobbered_ptr);
292
}
293
len = -nsize1_(mptr);
294
error_message("Error: "
295
"%s The malloc space #%d is at %p [user size=%d(0x%x)],"
296
" and was allocated from file \"%s\" at line %d."
297
" [The debug function %s() detected this error "
298
"in file \"%s\" at line %d.]",
299
nice_words, mid, mptr, len, len, mfile, mline,
300
name, file, line);
301
302
/* Print out contents of this allocation */
303
{
304
int i;
305
void *uptr = malloc2user_(mptr);
306
char *pmess;
307
pmess = temp;
308
for(i=0;i<(int)sizeof(temp);i++) {
309
int ch = ((unsigned char*)uptr)[i];
310
if ( isprint(ch) ) {
311
*pmess++ = ch;
312
} else {
313
*pmess++ = '\\';
314
*pmess++ = 'x';
315
(void)sprintf(pmess,"%02x",ch);
316
pmess+=2;
317
}
318
}
319
*pmess = 0;
320
error_message("Error: %p contains user data: %s", uptr, temp);
321
}
322
323
/* Try and print out table */
324
if (!malloc_watch) {
325
return;
326
}
327
mptr_walk = first_warrant_mptr;
328
if (mptr_walk != NULL) {
329
error_message("Active allocations: "
330
"count=%d, largest_size=%d, address range (%p,%p)",
331
id_counter, largest_size, smallest_addr, largest_addr);
332
do {
333
int size1;
334
int size2;
335
char *mfile_walk;
336
337
if ( mptr_walk > largest_addr || mptr_walk < smallest_addr ) {
338
error_message("Terminating list due to pointer corruption");
339
break;
340
}
341
size1 = -nsize1_(mptr_walk);
342
size2 = -nsize2_(mptr_walk);
343
mfile_walk = MFILE(mptr_walk);
344
error_message("#%d: addr=%p size1=%d size2=%d file=\"%.*s\" line=%d",
345
MID(mptr_walk), mptr_walk, size1, size2,
346
WARRANT_NAME_MAX, mfile_walk, MLINE(mptr_walk));
347
if ( size1 != size2 || size1 > largest_size || size1 < 0 ) {
348
error_message("Terminating list due to size corruption");
349
break;
350
}
351
mptr_walk = warrant_link_(mptr_walk);
352
} while (mptr_walk != NULL);
353
}
354
abort();
355
}
356
357
/* This function sets the clobber word and sets up the warrant for the input
358
* malloc pointer "mptr".
359
*/
360
static void
361
setup_space_and_issue_warrant(void *mptr, size_t size, const char *file, int line)
362
{
363
register int nbytes;
364
365
/*LINTED*/
366
nbytes = (int)size;
367
if ( nbytes > largest_size || largest_addr == NULL ) largest_size = nbytes;
368
/*LINTED*/
369
if ( mptr > largest_addr ) largest_addr = mptr;
370
/*LINTED*/
371
if ( mptr < smallest_addr || smallest_addr == NULL ) smallest_addr = mptr;
372
373
/* Must be done first: */
374
nsize1_(mptr) = -nbytes;
375
nsize2_(mptr) = -nbytes;
376
tail_nsize1_(mptr) = -nbytes;
377
tail_nsize2_(mptr) = -nbytes;
378
379
#ifdef LEFT_OVER_CHAR
380
/* Fill in those few extra bytes just before the tail Word structure */
381
{
382
register int trailing_extra_bytes;
383
/* LINTED */
384
trailing_extra_bytes = (int) (round_up_(nbytes) - nbytes);
385
if ( trailing_extra_bytes > 0 ) {
386
register char *p;
387
register int i;
388
p = ((char *) mptr) + sizeof(Word) + nbytes;
389
for (i = 0; i < trailing_extra_bytes; i++)
390
p[i] = LEFT_OVER_CHAR;
391
}
392
}
393
#endif
394
395
/* Fill out warrant */
396
if (malloc_watch) {
397
static Warrant_Record zero_warrant;
398
register void *p1,
399
*p2;
400
size_t len;
401
int start_pos = 0;
402
warrant_(mptr) = zero_warrant;
403
p1 = warrant_name_(mptr);
404
len = strlen(file);
405
if ( len > WARRANT_NAME_MAX ) {
406
/*LINTED*/
407
start_pos = (int)len - WARRANT_NAME_MAX;
408
}
409
p2 = ((char*)file) + start_pos;
410
/*LINTED*/
411
(void) memcpy(p1, p2, minimum(((int)len), WARRANT_NAME_MAX));
412
warrant_line_(mptr) = line;
413
warrant_id_(mptr) = ++id_counter;
414
warrant_link_(mptr) = first_warrant_mptr;
415
first_warrant_mptr = mptr;
416
}
417
}
418
419
/* This function checks the clobber words at the beginning and end of the
420
* allocated space.
421
*/
422
static void
423
memory_check(void *uptr, int mid, const char *mfile, int mline, const char *file, int line)
424
{
425
int neg_nbytes;
426
int nbytes;
427
428
debug_check = "pointer value itself";
429
clobbered_ptr = uptr;
430
if (uptr == NULL)
431
memory_error((void *) NULL, "memory_check", mid, mfile, mline, file, line);
432
433
/* Check both Word structures */
434
435
debug_check = "first beginning clobber word";
436
clobbered_ptr = (char*)&user_nsize1_(uptr);
437
neg_nbytes = user_nsize1_(uptr);
438
if (neg_nbytes >= 0)
439
memory_error(user2malloc_(uptr), "memory_check", mid, mfile, mline, file, line);
440
441
debug_check = "second beginning clobber word";
442
clobbered_ptr = (char*)&user_nsize2_(uptr);
443
if (neg_nbytes != user_nsize2_(uptr))
444
memory_error(user2malloc_(uptr), "memory_check", mid, mfile, mline, file, line);
445
446
debug_check = "first ending clobber word";
447
clobbered_ptr = (char*)&user_tail_nsize1_(uptr);
448
if (neg_nbytes != user_tail_nsize1_(uptr))
449
memory_error(user2malloc_(uptr), "memory_check", mid, mfile, mline, file, line);
450
451
debug_check = "second ending clobber word";
452
clobbered_ptr = (char*)&user_tail_nsize2_(uptr);
453
if (neg_nbytes != user_tail_nsize2_(uptr))
454
memory_error(user2malloc_(uptr), "memory_check", mid, mfile, mline, file, line);
455
456
/* Get a positive count of bytes */
457
nbytes = -neg_nbytes;
458
459
#ifdef LEFT_OVER_CHAR
460
{
461
/* Check those few extra bytes just before the tail Word structure */
462
register int trailing_extra_bytes;
463
register int i;
464
register char *p;
465
/* LINTED */
466
trailing_extra_bytes = (int) (round_up_(nbytes) - nbytes);
467
p = ((char *) (uptr)) + nbytes;
468
debug_check = "trailing left over area";
469
for (i = 0; i < trailing_extra_bytes; i++) {
470
clobbered_ptr = p+1;
471
if (p[i] != LEFT_OVER_CHAR) {
472
memory_error(user2malloc_(uptr), "memory_check", mid, mfile, mline, file, line);
473
}
474
}
475
}
476
#endif
477
478
/* Make sure debug_check is cleared */
479
debug_check = NULL;
480
}
481
482
/* This function looks for the given malloc pointer in the police line up
483
* and removes it from the warrant list.
484
* mptr The pointer to the malloc space being removed
485
*/
486
static int
487
remove_warrant(void *mptr)
488
{
489
void *mptr1,
490
*last_mptr1;
491
492
/* Free it up from the list */
493
if (malloc_watch && mptr != NULL) {
494
int found;
495
496
found = 0;
497
last_mptr1 = NULL;
498
mptr1 = first_warrant_mptr;
499
while (mptr1 != NULL) {
500
if (mptr1 == mptr) {
501
if (last_mptr1 == NULL)
502
first_warrant_mptr = warrant_link_(mptr1);
503
else
504
warrant_link_(last_mptr1) = warrant_link_(mptr1);
505
found = 1;
506
break;
507
}
508
last_mptr1 = mptr1;
509
mptr1 = warrant_link_(mptr1);
510
}
511
return found;
512
}
513
return 1;
514
}
515
516
static void
517
actual_free(void *uptr, const char *file, int line)
518
{
519
void *mptr;
520
const char *mfile;
521
int mline;
522
int mid;
523
if ( uptr == NULL )
524
return;
525
mptr = user2malloc_(uptr);
526
memory_check(uptr, (mid=MID(mptr)), (mfile=MFILE(mptr)), (mline=MLINE(mptr)), file, line);
527
if (malloc_watch && remove_warrant(mptr)==0 )
528
memory_check(uptr, mid, mfile, mline, file, line);
529
#ifdef FREED_CHAR
530
if ( mptr!=NULL ) {
531
size_t nbytes = -nsize1_(mptr);
532
/* LINTED */
533
(void)memset(mptr, FREED_CHAR, rbytes_(nbytes));
534
}
535
#endif
536
free(mptr);
537
}
538
539
#ifdef MAX_FREE_DELAY_COUNT
540
541
static void *free_delay[MAX_FREE_DELAY_COUNT];
542
static int free_delay_pos = 0;
543
544
static void
545
delayed_free(void *uptr, const char* file, int line)
546
{
547
void *mptr;
548
void *olduptr = free_delay[free_delay_pos];
549
size_t nbytes;
550
if ( uptr==NULL )
551
return;
552
mptr = user2malloc_(uptr);
553
memory_check(uptr, MID(mptr), MFILE(mptr), MLINE(mptr), file, line);
554
if ( olduptr!=NULL ) {
555
actual_free(olduptr, file, line);
556
}
557
free_delay[free_delay_pos] = uptr;
558
free_delay_pos++;
559
free_delay_pos = free_delay_pos % MAX_FREE_DELAY_COUNT;
560
nbytes = -user_nsize1_(uptr);
561
#ifdef FREED_CHAR
562
(void)memset(uptr, FREED_CHAR, (size_t)nbytes);
563
#endif
564
}
565
566
static void
567
delayed_free_all(const char *file, int line)
568
{
569
int i;
570
for ( i=0; i< MAX_FREE_DELAY_COUNT; i++) {
571
void *olduptr = free_delay[i];
572
free_delay[i] = NULL;
573
if ( olduptr!=NULL ) {
574
actual_free(olduptr, file, line);
575
}
576
}
577
}
578
579
#endif
580
581
void
582
debug_free(void *uptr, const char *file, int line)
583
{
584
int mid = 0;
585
586
if (uptr == NULL)
587
memory_error((void *) NULL, "debug_free", mid, file, line, file, line);
588
#ifdef MAX_FREE_DELAY_COUNT
589
delayed_free(uptr, file, line);
590
#else
591
actual_free(uptr, file, line);
592
#endif
593
}
594
595
/* This function calls malloc(). */
596
void *
597
debug_malloc(size_t nbytes, const char *file, int line)
598
{
599
void *mptr;
600
void *uptr;
601
int mid = id_counter;
602
603
/*LINTED*/
604
if ((int)nbytes <= 0)
605
memory_error((void *) NULL, "debug_malloc", mid, file, line, file, line);
606
/* LINTED */
607
mptr = malloc(rbytes_(nbytes));
608
if (mptr == NULL)
609
memory_error((void *) NULL, "debug_malloc", mid, file, line, file, line);
610
setup_space_and_issue_warrant(mptr, nbytes, file, line);
611
uptr = malloc2user_(mptr);
612
#ifdef ALLOC_CHAR
613
(void)memset(uptr, ALLOC_CHAR, (size_t)nbytes);
614
#endif
615
return uptr;
616
}
617
618
void *
619
debug_realloc(void *uptr, size_t nbytes, const char *file, int line)
620
{
621
void *mptr;
622
void *oldmptr;
623
void *newuptr;
624
size_t oldnbytes;
625
int mid = id_counter;
626
627
oldmptr = user2malloc_(uptr);
628
oldnbytes = 0;
629
if ((int)nbytes <= 0)
630
memory_error(oldmptr, "debug_realloc", mid, file, line, file, line);
631
if (uptr != NULL) {
632
memory_check(uptr, MID(oldmptr), MFILE(oldmptr), MLINE(oldmptr), file, line);
633
oldnbytes = -user_nsize1_(uptr);
634
if ( malloc_watch && remove_warrant(oldmptr)==0 )
635
memory_check(uptr, MID(oldmptr), MFILE(oldmptr), MLINE(oldmptr), file, line);
636
}
637
if (uptr == NULL) {
638
/* LINTED */
639
mptr = malloc(rbytes_(nbytes));
640
} else {
641
/* LINTED */
642
mptr = realloc(oldmptr, rbytes_(nbytes));
643
}
644
if (mptr == NULL)
645
memory_error(oldmptr, "debug_realloc", mid, file, line, file, line);
646
setup_space_and_issue_warrant(mptr, nbytes, file, line);
647
newuptr = malloc2user_(mptr);
648
#ifdef ALLOC_CHAR
649
if (uptr == NULL)
650
(void)memset(newuptr, ALLOC_CHAR, (size_t)nbytes);
651
else if ( nbytes > oldnbytes )
652
(void)memset(((char*)newuptr)+oldnbytes, ALLOC_CHAR, (size_t)nbytes-oldnbytes);
653
#endif
654
return newuptr;
655
}
656
657
/* This function calls calloc(). */
658
void *
659
debug_calloc(size_t nelem, size_t elsize, const char *file, int line)
660
{
661
void *mptr;
662
size_t nbytes;
663
int mid = id_counter;
664
665
nbytes = nelem*elsize;
666
/*LINTED*/
667
if ((int)nbytes <= 0)
668
memory_error((void *) NULL, "debug_calloc", mid, file, line, file, line);
669
/* LINTED */
670
mptr = calloc(rbytes_(nbytes),1);
671
if (mptr == NULL)
672
memory_error((void *) NULL, "debug_calloc", mid, file, line, file, line);
673
setup_space_and_issue_warrant(mptr, nbytes, file, line);
674
return malloc2user_(mptr);
675
}
676
677
/* This function replaces strdup(). */
678
char *
679
debug_strdup(const char *s1, const char *file, int line)
680
{
681
void *mptr;
682
void *uptr;
683
size_t nbytes;
684
int mid = id_counter;
685
686
if (s1 == NULL)
687
memory_error((void *) NULL, "debug_strdup", mid, file, line, file, line);
688
nbytes = strlen(s1)+1;
689
/*LINTED*/
690
if ((int)nbytes < 0)
691
memory_error((void *) NULL, "debug_strdup", mid, file, line, file, line);
692
/* LINTED */
693
mptr = malloc(rbytes_(nbytes));
694
if (mptr == NULL)
695
memory_error((void *) NULL, "debug_strdup", mid, file, line, file, line);
696
setup_space_and_issue_warrant(mptr, nbytes, file, line);
697
uptr = malloc2user_(mptr);
698
(void)strcpy((char*)uptr, s1);
699
return (char*)uptr;
700
}
701
702
void
703
debug_malloc_verify(const char *file, int line)
704
{
705
void *mptr;
706
707
#ifdef MAX_FREE_DELAY_COUNT
708
delayed_free_all(file,line);
709
#endif
710
711
if (!malloc_watch) {
712
return;
713
}
714
mptr = first_warrant_mptr;
715
if (mptr != NULL) {
716
/* Check all this memory first */
717
do {
718
memory_check(malloc2user_(mptr), MID(mptr), MFILE(mptr), MLINE(mptr), file, line);
719
mptr = warrant_link_(mptr);
720
} while (mptr != NULL);
721
}
722
}
723
724
/* Report outstanding space warrants to console. */
725
void
726
debug_malloc_police(const char *file, int line)
727
{
728
void *mptr;
729
730
#ifdef MAX_FREE_DELAY_COUNT
731
delayed_free_all(file,line);
732
#endif
733
734
if (!malloc_watch) {
735
return;
736
}
737
738
mptr = first_warrant_mptr;
739
if (mptr != NULL) {
740
debug_malloc_verify(file, line);
741
/* Now issue warrants */
742
mptr = first_warrant_mptr;
743
do {
744
error_message("Outstanding space warrant: %p (%d bytes) allocated by %s at line %d, allocation #%d",
745
mptr, -nsize1_(mptr), warrant_name_(mptr),
746
warrant_line_(mptr), warrant_id_(mptr));
747
748
mptr = warrant_link_(mptr);
749
} while (mptr != NULL);
750
}
751
}
752
753
#else
754
755
void
756
debug_malloc_verify(const char *file, int line)
757
{
758
file = file;
759
line = line;
760
}
761
762
void
763
debug_malloc_police(const char *file, int line)
764
{
765
file = file;
766
line = line;
767
}
768
769
#endif
770
771