1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
/* More debugging hooks for `malloc'.
Copyright 1991 Free Software Foundation
Written April 2, 1991 by John Gilmore of Cygnus Support
Based on mcheck.c by Mike Haertel.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include "ansidecl.h"
/* size_t may be defined in the system-supplied stdio.h. */
/* So just kludge it. */
#define size_t unsigned int
#define ptrdiff_t int
#define __ONEFILE
#include <stdlib.h>
#include "gmalloc.h"
extern char *getenv();
FILE *mallstream;
char mallenv[] = "MALLOC_TRACE";
static char mallbuf[BUFSIZ]; /* Buffer for the output */
/* Address to breakpoint on accesses to... */
PTR mallwatch;
/* Old hook values. */
static void EXFUN((*old_free_hook), (PTR ptr));
static PTR EXFUN((*old_malloc_hook), (size_t size));
static PTR EXFUN((*old_realloc_hook), (PTR ptr, size_t size));
/* This function is called when the block being alloc'd, realloc'd, or
freed has an address matching the variable "mallwatch". In a debugger,
set "mallwatch" to the address of interest, then put a breakpoint on
tr_break. */
void
tr_break()
{
;
}
static void
DEFUN(tr_freehook, (ptr), PTR ptr)
{
fprintf(mallstream, "- %08x\n", ptr); /* Be sure to print it first */
if (ptr == mallwatch)
tr_break();
__free_hook = old_free_hook;
free(ptr);
__free_hook = tr_freehook;
}
static PTR
DEFUN(tr_mallochook, (size), size_t size)
{
PTR hdr;
__malloc_hook = old_malloc_hook;
hdr = malloc(size);
__malloc_hook = tr_mallochook;
/* We could be printing a NULL here; that's OK */
fprintf (mallstream, "+ %08x %x\n", hdr, size);
if (hdr == mallwatch)
tr_break();
return hdr;
}
static PTR
DEFUN(tr_reallochook, (ptr, size), PTR ptr AND size_t size)
{
PTR hdr;
if (ptr == mallwatch)
tr_break();
__free_hook = old_free_hook;
__malloc_hook = old_malloc_hook;
__realloc_hook = old_realloc_hook;
hdr = realloc(ptr, size);
__free_hook = tr_freehook;
__malloc_hook = tr_mallochook;
__realloc_hook = tr_reallochook;
if (hdr == NULL) {
fprintf (mallstream, "! %08x %x\n", ptr, size); /* Failed realloc */
} else {
fprintf (mallstream, "< %08x\n> %08x %x\n", ptr, hdr, size);
}
if (hdr == mallwatch)
tr_break();
return hdr;
}
void
mtrace()
{
char *mallfile;
mallfile = getenv (mallenv);
if (mallfile) {
mallstream = fopen (mallfile, "w");
if (mallstream) {
/* Be sure it doesn't malloc its buffer! */
setbuf (mallstream, mallbuf);
fprintf (mallstream, "= Start\n");
old_free_hook = __free_hook;
__free_hook = tr_freehook;
old_malloc_hook = __malloc_hook;
__malloc_hook = tr_mallochook;
old_realloc_hook = __realloc_hook;
__realloc_hook = tr_reallochook;
}
}
}
|